Source file src/runtime/syscall_solaris.go

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import "unsafe"
     8  
     9  var (
    10  	libc_chdir,
    11  	libc_chroot,
    12  	libc_close,
    13  	libc_execve,
    14  	libc_fcntl,
    15  	libc_forkx,
    16  	libc_gethostname,
    17  	libc_getpid,
    18  	libc_ioctl,
    19  	libc_setgid,
    20  	libc_setgroups,
    21  	libc_setrlimit,
    22  	libc_setsid,
    23  	libc_setuid,
    24  	libc_setpgid,
    25  	libc_syscall,
    26  	libc_issetugid,
    27  	libc_wait4 libcFunc
    28  )
    29  
    30  // Many of these are exported via linkname to assembly in the syscall
    31  // package.
    32  
    33  //go:nosplit
    34  //go:linkname syscall_sysvicall6
    35  //go:cgo_unsafe_args
    36  func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
    37  	call := libcall{
    38  		fn:   fn,
    39  		n:    nargs,
    40  		args: uintptr(unsafe.Pointer(&a1)),
    41  	}
    42  	entersyscallblock()
    43  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
    44  	exitsyscall()
    45  	return call.r1, call.r2, call.err
    46  }
    47  
    48  //go:nosplit
    49  //go:linkname syscall_rawsysvicall6
    50  //go:cgo_unsafe_args
    51  func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
    52  	call := libcall{
    53  		fn:   fn,
    54  		n:    nargs,
    55  		args: uintptr(unsafe.Pointer(&a1)),
    56  	}
    57  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
    58  	return call.r1, call.r2, call.err
    59  }
    60  
    61  // TODO(aram): Once we remove all instances of C calling sysvicallN, make
    62  // sysvicallN return errors and replace the body of the following functions
    63  // with calls to sysvicallN.
    64  
    65  //go:nosplit
    66  //go:linkname syscall_chdir
    67  func syscall_chdir(path uintptr) (err uintptr) {
    68  	call := libcall{
    69  		fn:   uintptr(unsafe.Pointer(&libc_chdir)),
    70  		n:    1,
    71  		args: uintptr(unsafe.Pointer(&path)),
    72  	}
    73  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
    74  	return call.err
    75  }
    76  
    77  //go:nosplit
    78  //go:linkname syscall_chroot
    79  func syscall_chroot(path uintptr) (err uintptr) {
    80  	call := libcall{
    81  		fn:   uintptr(unsafe.Pointer(&libc_chroot)),
    82  		n:    1,
    83  		args: uintptr(unsafe.Pointer(&path)),
    84  	}
    85  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
    86  	return call.err
    87  }
    88  
    89  // like close, but must not split stack, for forkx.
    90  //
    91  //go:nosplit
    92  //go:linkname syscall_close
    93  func syscall_close(fd int32) int32 {
    94  	return int32(sysvicall1(&libc_close, uintptr(fd)))
    95  }
    96  
    97  const _F_DUP2FD = 0x9
    98  
    99  //go:nosplit
   100  //go:linkname syscall_dup2
   101  func syscall_dup2(oldfd, newfd uintptr) (val, err uintptr) {
   102  	return syscall_fcntl(oldfd, _F_DUP2FD, newfd)
   103  }
   104  
   105  //go:nosplit
   106  //go:linkname syscall_execve
   107  //go:cgo_unsafe_args
   108  func syscall_execve(path, argv, envp uintptr) (err uintptr) {
   109  	call := libcall{
   110  		fn:   uintptr(unsafe.Pointer(&libc_execve)),
   111  		n:    3,
   112  		args: uintptr(unsafe.Pointer(&path)),
   113  	}
   114  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   115  	return call.err
   116  }
   117  
   118  // like exit, but must not split stack, for forkx.
   119  //
   120  //go:nosplit
   121  //go:linkname syscall_exit
   122  func syscall_exit(code uintptr) {
   123  	sysvicall1(&libc_exit, code)
   124  }
   125  
   126  //go:nosplit
   127  //go:linkname syscall_fcntl
   128  //go:cgo_unsafe_args
   129  func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) {
   130  	call := libcall{
   131  		fn:   uintptr(unsafe.Pointer(&libc_fcntl)),
   132  		n:    3,
   133  		args: uintptr(unsafe.Pointer(&fd)),
   134  	}
   135  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   136  	return call.r1, call.err
   137  }
   138  
   139  //go:nosplit
   140  //go:linkname syscall_forkx
   141  func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) {
   142  	call := libcall{
   143  		fn:   uintptr(unsafe.Pointer(&libc_forkx)),
   144  		n:    1,
   145  		args: uintptr(unsafe.Pointer(&flags)),
   146  	}
   147  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   148  	if int(call.r1) != -1 {
   149  		call.err = 0
   150  	}
   151  	return call.r1, call.err
   152  }
   153  
   154  //go:linkname syscall_gethostname
   155  func syscall_gethostname() (name string, err uintptr) {
   156  	cname := new([_MAXHOSTNAMELEN]byte)
   157  	var args = [2]uintptr{uintptr(unsafe.Pointer(&cname[0])), _MAXHOSTNAMELEN}
   158  	call := libcall{
   159  		fn:   uintptr(unsafe.Pointer(&libc_gethostname)),
   160  		n:    2,
   161  		args: uintptr(unsafe.Pointer(&args[0])),
   162  	}
   163  	entersyscallblock()
   164  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   165  	exitsyscall()
   166  	if call.r1 != 0 {
   167  		return "", call.err
   168  	}
   169  	cname[_MAXHOSTNAMELEN-1] = 0
   170  	return gostringnocopy(&cname[0]), 0
   171  }
   172  
   173  //go:nosplit
   174  //go:linkname syscall_getpid
   175  func syscall_getpid() (pid, err uintptr) {
   176  	call := libcall{
   177  		fn:   uintptr(unsafe.Pointer(&libc_getpid)),
   178  		n:    0,
   179  		args: uintptr(unsafe.Pointer(&libc_getpid)), // it's unused but must be non-nil, otherwise crashes
   180  	}
   181  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   182  	return call.r1, call.err
   183  }
   184  
   185  //go:nosplit
   186  //go:linkname syscall_ioctl
   187  //go:cgo_unsafe_args
   188  func syscall_ioctl(fd, req, arg uintptr) (err uintptr) {
   189  	call := libcall{
   190  		fn:   uintptr(unsafe.Pointer(&libc_ioctl)),
   191  		n:    3,
   192  		args: uintptr(unsafe.Pointer(&fd)),
   193  	}
   194  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   195  	return call.err
   196  }
   197  
   198  // This is syscall.RawSyscall, it exists to satisfy some build dependency,
   199  // but it doesn't work.
   200  //
   201  //go:linkname syscall_rawsyscall
   202  func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
   203  	panic("RawSyscall not available on Solaris")
   204  }
   205  
   206  // This is syscall.RawSyscall6, it exists to avoid a linker error because
   207  // syscall.RawSyscall6 is already declared. See golang.org/issue/24357
   208  //
   209  //go:linkname syscall_rawsyscall6
   210  func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
   211  	panic("RawSyscall6 not available on Solaris")
   212  }
   213  
   214  //go:nosplit
   215  //go:linkname syscall_setgid
   216  func syscall_setgid(gid uintptr) (err uintptr) {
   217  	call := libcall{
   218  		fn:   uintptr(unsafe.Pointer(&libc_setgid)),
   219  		n:    1,
   220  		args: uintptr(unsafe.Pointer(&gid)),
   221  	}
   222  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   223  	return call.err
   224  }
   225  
   226  //go:nosplit
   227  //go:linkname syscall_setgroups
   228  //go:cgo_unsafe_args
   229  func syscall_setgroups(ngid, gid uintptr) (err uintptr) {
   230  	call := libcall{
   231  		fn:   uintptr(unsafe.Pointer(&libc_setgroups)),
   232  		n:    2,
   233  		args: uintptr(unsafe.Pointer(&ngid)),
   234  	}
   235  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   236  	return call.err
   237  }
   238  
   239  //go:nosplit
   240  //go:linkname syscall_setrlimit
   241  //go:cgo_unsafe_args
   242  func syscall_setrlimit(which uintptr, lim unsafe.Pointer) (err uintptr) {
   243  	call := libcall{
   244  		fn:   uintptr(unsafe.Pointer(&libc_setrlimit)),
   245  		n:    2,
   246  		args: uintptr(unsafe.Pointer(&which)),
   247  	}
   248  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   249  	return call.err
   250  }
   251  
   252  //go:nosplit
   253  //go:linkname syscall_setsid
   254  func syscall_setsid() (pid, err uintptr) {
   255  	call := libcall{
   256  		fn:   uintptr(unsafe.Pointer(&libc_setsid)),
   257  		n:    0,
   258  		args: uintptr(unsafe.Pointer(&libc_setsid)), // it's unused but must be non-nil, otherwise crashes
   259  	}
   260  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   261  	return call.r1, call.err
   262  }
   263  
   264  //go:nosplit
   265  //go:linkname syscall_setuid
   266  func syscall_setuid(uid uintptr) (err uintptr) {
   267  	call := libcall{
   268  		fn:   uintptr(unsafe.Pointer(&libc_setuid)),
   269  		n:    1,
   270  		args: uintptr(unsafe.Pointer(&uid)),
   271  	}
   272  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   273  	return call.err
   274  }
   275  
   276  //go:nosplit
   277  //go:linkname syscall_setpgid
   278  //go:cgo_unsafe_args
   279  func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
   280  	call := libcall{
   281  		fn:   uintptr(unsafe.Pointer(&libc_setpgid)),
   282  		n:    2,
   283  		args: uintptr(unsafe.Pointer(&pid)),
   284  	}
   285  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   286  	return call.err
   287  }
   288  
   289  //go:linkname syscall_syscall
   290  //go:cgo_unsafe_args
   291  func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
   292  	call := libcall{
   293  		fn:   uintptr(unsafe.Pointer(&libc_syscall)),
   294  		n:    4,
   295  		args: uintptr(unsafe.Pointer(&trap)),
   296  	}
   297  	entersyscallblock()
   298  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   299  	exitsyscall()
   300  	return call.r1, call.r2, call.err
   301  }
   302  
   303  //go:linkname syscall_wait4
   304  //go:cgo_unsafe_args
   305  func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.Pointer) (wpid int, err uintptr) {
   306  	call := libcall{
   307  		fn:   uintptr(unsafe.Pointer(&libc_wait4)),
   308  		n:    4,
   309  		args: uintptr(unsafe.Pointer(&pid)),
   310  	}
   311  	entersyscallblock()
   312  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   313  	exitsyscall()
   314  	KeepAlive(wstatus)
   315  	KeepAlive(rusage)
   316  	return int(call.r1), call.err
   317  }
   318  
   319  //go:nosplit
   320  //go:linkname syscall_write
   321  //go:cgo_unsafe_args
   322  func syscall_write(fd, buf, nbyte uintptr) (n, err uintptr) {
   323  	call := libcall{
   324  		fn:   uintptr(unsafe.Pointer(&libc_write)),
   325  		n:    3,
   326  		args: uintptr(unsafe.Pointer(&fd)),
   327  	}
   328  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   329  	return call.r1, call.err
   330  }
   331  

View as plain text