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

View as plain text