...

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

View as plain text