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

View as plain text