github.com/zxy12/golang151_with_comment@v0.0.0-20190507085033-721809559d3c/syscall/syscall_solaris.go (about)

     1  // Copyright 2009 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  // Solaris system calls.
     6  // This file is compiled as ordinary Go code,
     7  // but it is also input to mksyscall,
     8  // which parses the //sys lines and generates system call stubs.
     9  // Note that sometimes we use a lowercase //sys name and wrap
    10  // it in our own nicer implementation, either here or in
    11  // syscall_solaris.go or syscall_unix.go.
    12  
    13  package syscall
    14  
    15  import "unsafe"
    16  
    17  // Implemented in asm_solaris_amd64.s.
    18  func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    19  func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    20  
    21  type SockaddrDatalink struct {
    22  	Family uint16
    23  	Index  uint16
    24  	Type   uint8
    25  	Nlen   uint8
    26  	Alen   uint8
    27  	Slen   uint8
    28  	Data   [244]int8
    29  	raw    RawSockaddrDatalink
    30  }
    31  
    32  func clen(n []byte) int {
    33  	for i := 0; i < len(n); i++ {
    34  		if n[i] == 0 {
    35  			return i
    36  		}
    37  	}
    38  	return len(n)
    39  }
    40  
    41  // ParseDirent parses up to max directory entries in buf,
    42  // appending the names to names.  It returns the number
    43  // bytes consumed from buf, the number of entries added
    44  // to names, and the new names slice.
    45  func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
    46  	origlen := len(buf)
    47  	for max != 0 && len(buf) > 0 {
    48  		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
    49  		if dirent.Reclen == 0 {
    50  			buf = nil
    51  			break
    52  		}
    53  		buf = buf[dirent.Reclen:]
    54  		if dirent.Ino == 0 { // File absent in directory.
    55  			continue
    56  		}
    57  		bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
    58  		var name = string(bytes[0:clen(bytes[:])])
    59  		if name == "." || name == ".." { // Useless names
    60  			continue
    61  		}
    62  		max--
    63  		count++
    64  		names = append(names, name)
    65  	}
    66  	return origlen - len(buf), count, names
    67  }
    68  
    69  func pipe() (r uintptr, w uintptr, err uintptr)
    70  
    71  func Pipe(p []int) (err error) {
    72  	if len(p) != 2 {
    73  		return EINVAL
    74  	}
    75  	r0, w0, e1 := pipe()
    76  	if e1 != 0 {
    77  		err = Errno(e1)
    78  	}
    79  	p[0], p[1] = int(r0), int(w0)
    80  	return
    81  }
    82  
    83  func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
    84  	if sa.Port < 0 || sa.Port > 0xFFFF {
    85  		return nil, 0, EINVAL
    86  	}
    87  	sa.raw.Family = AF_INET
    88  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
    89  	p[0] = byte(sa.Port >> 8)
    90  	p[1] = byte(sa.Port)
    91  	for i := 0; i < len(sa.Addr); i++ {
    92  		sa.raw.Addr[i] = sa.Addr[i]
    93  	}
    94  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
    95  }
    96  
    97  func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
    98  	if sa.Port < 0 || sa.Port > 0xFFFF {
    99  		return nil, 0, EINVAL
   100  	}
   101  	sa.raw.Family = AF_INET6
   102  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
   103  	p[0] = byte(sa.Port >> 8)
   104  	p[1] = byte(sa.Port)
   105  	sa.raw.Scope_id = sa.ZoneId
   106  	for i := 0; i < len(sa.Addr); i++ {
   107  		sa.raw.Addr[i] = sa.Addr[i]
   108  	}
   109  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
   110  }
   111  
   112  func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
   113  	name := sa.Name
   114  	n := len(name)
   115  	if n >= len(sa.raw.Path) {
   116  		return nil, 0, EINVAL
   117  	}
   118  	sa.raw.Family = AF_UNIX
   119  	for i := 0; i < n; i++ {
   120  		sa.raw.Path[i] = int8(name[i])
   121  	}
   122  	// length is family (uint16), name, NUL.
   123  	sl := _Socklen(2)
   124  	if n > 0 {
   125  		sl += _Socklen(n) + 1
   126  	}
   127  	if sa.raw.Path[0] == '@' {
   128  		sa.raw.Path[0] = 0
   129  		// Don't count trailing NUL for abstract address.
   130  		sl--
   131  	}
   132  
   133  	return unsafe.Pointer(&sa.raw), sl, nil
   134  }
   135  
   136  func Getsockname(fd int) (sa Sockaddr, err error) {
   137  	var rsa RawSockaddrAny
   138  	var len _Socklen = SizeofSockaddrAny
   139  	if err = getsockname(fd, &rsa, &len); err != nil {
   140  		return
   141  	}
   142  	return anyToSockaddr(&rsa)
   143  }
   144  
   145  // The const provides a compile-time constant so clients
   146  // can adjust to whether there is a working Getwd and avoid
   147  // even linking this function into the binary.  See ../os/getwd.go.
   148  const ImplementsGetwd = false
   149  
   150  func Getwd() (string, error) { return "", ENOTSUP }
   151  
   152  /*
   153   * Wrapped
   154   */
   155  
   156  //sysnb	getgroups(ngid int, gid *_Gid_t) (n int, err error)
   157  //sysnb	setgroups(ngid int, gid *_Gid_t) (err error)
   158  
   159  func Getgroups() (gids []int, err error) {
   160  	n, err := getgroups(0, nil)
   161  	if err != nil {
   162  		return nil, err
   163  	}
   164  	if n == 0 {
   165  		return nil, nil
   166  	}
   167  
   168  	// Sanity check group count.  Max is 16 on BSD.
   169  	if n < 0 || n > 1000 {
   170  		return nil, EINVAL
   171  	}
   172  
   173  	a := make([]_Gid_t, n)
   174  	n, err = getgroups(n, &a[0])
   175  	if err != nil {
   176  		return nil, err
   177  	}
   178  	gids = make([]int, n)
   179  	for i, v := range a[0:n] {
   180  		gids[i] = int(v)
   181  	}
   182  	return
   183  }
   184  
   185  func Setgroups(gids []int) (err error) {
   186  	if len(gids) == 0 {
   187  		return setgroups(0, nil)
   188  	}
   189  
   190  	a := make([]_Gid_t, len(gids))
   191  	for i, v := range gids {
   192  		a[i] = _Gid_t(v)
   193  	}
   194  	return setgroups(len(a), &a[0])
   195  }
   196  
   197  func ReadDirent(fd int, buf []byte) (n int, err error) {
   198  	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
   199  	// TODO(rsc): Can we use a single global basep for all calls?
   200  	return Getdents(fd, buf, new(uintptr))
   201  }
   202  
   203  // Wait status is 7 bits at bottom, either 0 (exited),
   204  // 0x7F (stopped), or a signal number that caused an exit.
   205  // The 0x80 bit is whether there was a core dump.
   206  // An extra number (exit code, signal causing a stop)
   207  // is in the high bits.
   208  
   209  type WaitStatus uint32
   210  
   211  const (
   212  	mask  = 0x7F
   213  	core  = 0x80
   214  	shift = 8
   215  
   216  	exited  = 0
   217  	stopped = 0x7F
   218  )
   219  
   220  func (w WaitStatus) Exited() bool { return w&mask == exited }
   221  
   222  func (w WaitStatus) ExitStatus() int {
   223  	if w&mask != exited {
   224  		return -1
   225  	}
   226  	return int(w >> shift)
   227  }
   228  
   229  func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
   230  
   231  func (w WaitStatus) Signal() Signal {
   232  	sig := Signal(w & mask)
   233  	if sig == stopped || sig == 0 {
   234  		return -1
   235  	}
   236  	return sig
   237  }
   238  
   239  func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
   240  
   241  func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
   242  
   243  func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
   244  
   245  func (w WaitStatus) StopSignal() Signal {
   246  	if !w.Stopped() {
   247  		return -1
   248  	}
   249  	return Signal(w>>shift) & 0xFF
   250  }
   251  
   252  func (w WaitStatus) TrapCause() int { return -1 }
   253  
   254  func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr)
   255  
   256  func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
   257  	r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage)
   258  	if e1 != 0 {
   259  		err = Errno(e1)
   260  	}
   261  	return int(r0), err
   262  }
   263  
   264  func gethostname() (name string, err uintptr)
   265  
   266  func Gethostname() (name string, err error) {
   267  	name, e1 := gethostname()
   268  	if e1 != 0 {
   269  		err = Errno(e1)
   270  	}
   271  	return name, err
   272  }
   273  
   274  func UtimesNano(path string, ts []Timespec) (err error) {
   275  	if len(ts) != 2 {
   276  		return EINVAL
   277  	}
   278  	var tv [2]Timeval
   279  	for i := 0; i < 2; i++ {
   280  		tv[i].Sec = ts[i].Sec
   281  		tv[i].Usec = ts[i].Nsec / 1000
   282  	}
   283  	return Utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   284  }
   285  
   286  //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
   287  
   288  // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
   289  func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
   290  	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
   291  	if e1 != 0 {
   292  		return e1
   293  	}
   294  	return nil
   295  }
   296  
   297  func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
   298  	switch rsa.Addr.Family {
   299  	case AF_UNIX:
   300  		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
   301  		sa := new(SockaddrUnix)
   302  		// Assume path ends at NUL.
   303  		// This is not technically the Solaris semantics for
   304  		// abstract Unix domain sockets -- they are supposed
   305  		// to be uninterpreted fixed-size binary blobs -- but
   306  		// everyone uses this convention.
   307  		n := 0
   308  		for n < len(pp.Path) && pp.Path[n] != 0 {
   309  			n++
   310  		}
   311  		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
   312  		sa.Name = string(bytes)
   313  		return sa, nil
   314  
   315  	case AF_INET:
   316  		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
   317  		sa := new(SockaddrInet4)
   318  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   319  		sa.Port = int(p[0])<<8 + int(p[1])
   320  		for i := 0; i < len(sa.Addr); i++ {
   321  			sa.Addr[i] = pp.Addr[i]
   322  		}
   323  		return sa, nil
   324  
   325  	case AF_INET6:
   326  		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
   327  		sa := new(SockaddrInet6)
   328  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   329  		sa.Port = int(p[0])<<8 + int(p[1])
   330  		sa.ZoneId = pp.Scope_id
   331  		for i := 0; i < len(sa.Addr); i++ {
   332  			sa.Addr[i] = pp.Addr[i]
   333  		}
   334  		return sa, nil
   335  	}
   336  	return nil, EAFNOSUPPORT
   337  }
   338  
   339  //sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libsocket.accept
   340  
   341  func Accept(fd int) (nfd int, sa Sockaddr, err error) {
   342  	var rsa RawSockaddrAny
   343  	var len _Socklen = SizeofSockaddrAny
   344  	nfd, err = accept(fd, &rsa, &len)
   345  	if err != nil {
   346  		return
   347  	}
   348  	sa, err = anyToSockaddr(&rsa)
   349  	if err != nil {
   350  		Close(nfd)
   351  		nfd = 0
   352  	}
   353  	return
   354  }
   355  
   356  func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
   357  	var msg Msghdr
   358  	var rsa RawSockaddrAny
   359  	msg.Name = (*byte)(unsafe.Pointer(&rsa))
   360  	msg.Namelen = uint32(SizeofSockaddrAny)
   361  	var iov Iovec
   362  	if len(p) > 0 {
   363  		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
   364  		iov.SetLen(len(p))
   365  	}
   366  	var dummy int8
   367  	if len(oob) > 0 {
   368  		// receive at least one normal byte
   369  		if len(p) == 0 {
   370  			iov.Base = &dummy
   371  			iov.SetLen(1)
   372  		}
   373  		msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
   374  	}
   375  	msg.Iov = &iov
   376  	msg.Iovlen = 1
   377  	if n, err = recvmsg(fd, &msg, flags); err != nil {
   378  		return
   379  	}
   380  	oobn = int(msg.Accrightslen)
   381  	// source address is only specified if the socket is unconnected
   382  	if rsa.Addr.Family != AF_UNSPEC {
   383  		from, err = anyToSockaddr(&rsa)
   384  	}
   385  	return
   386  }
   387  
   388  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
   389  	_, err = SendmsgN(fd, p, oob, to, flags)
   390  	return
   391  }
   392  
   393  //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.sendmsg
   394  
   395  func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
   396  	var ptr unsafe.Pointer
   397  	var salen _Socklen
   398  	if to != nil {
   399  		ptr, salen, err = to.sockaddr()
   400  		if err != nil {
   401  			return 0, err
   402  		}
   403  	}
   404  	var msg Msghdr
   405  	msg.Name = (*byte)(unsafe.Pointer(ptr))
   406  	msg.Namelen = uint32(salen)
   407  	var iov Iovec
   408  	if len(p) > 0 {
   409  		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
   410  		iov.SetLen(len(p))
   411  	}
   412  	var dummy int8
   413  	if len(oob) > 0 {
   414  		// send at least one normal byte
   415  		if len(p) == 0 {
   416  			iov.Base = &dummy
   417  			iov.SetLen(1)
   418  		}
   419  		msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
   420  	}
   421  	msg.Iov = &iov
   422  	msg.Iovlen = 1
   423  	if n, err = sendmsg(fd, &msg, flags); err != nil {
   424  		return 0, err
   425  	}
   426  	if len(oob) > 0 && len(p) == 0 {
   427  		n = 0
   428  	}
   429  	return n, nil
   430  }
   431  
   432  /*
   433   * Exposed directly
   434   */
   435  //sys	Access(path string, mode uint32) (err error)
   436  //sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
   437  //sys	Chdir(path string) (err error)
   438  //sys	Chmod(path string, mode uint32) (err error)
   439  //sys	Chown(path string, uid int, gid int) (err error)
   440  //sys	Chroot(path string) (err error)
   441  //sys	Close(fd int) (err error)
   442  //sys	Dup(fd int) (nfd int, err error)
   443  //sys	Exit(code int)
   444  //sys	Fchdir(fd int) (err error)
   445  //sys	Fchmod(fd int, mode uint32) (err error)
   446  //sys	Fchown(fd int, uid int, gid int) (err error)
   447  //sys	Fpathconf(fd int, name int) (val int, err error)
   448  //sys	Fstat(fd int, stat *Stat_t) (err error)
   449  //sys	Getdents(fd int, buf []byte, basep *uintptr) (n int, err error)
   450  //sysnb	Getgid() (gid int)
   451  //sysnb	Getpid() (pid int)
   452  //sys	Geteuid() (euid int)
   453  //sys	Getegid() (egid int)
   454  //sys	Getppid() (ppid int)
   455  //sys	Getpriority(which int, who int) (n int, err error)
   456  //sysnb	Getrlimit(which int, lim *Rlimit) (err error)
   457  //sysnb	Gettimeofday(tv *Timeval) (err error)
   458  //sysnb	Getuid() (uid int)
   459  //sys	Kill(pid int, signum Signal) (err error)
   460  //sys	Lchown(path string, uid int, gid int) (err error)
   461  //sys	Link(path string, link string) (err error)
   462  //sys	Listen(s int, backlog int) (err error) = libsocket.listen
   463  //sys	Lstat(path string, stat *Stat_t) (err error)
   464  //sys	Mkdir(path string, mode uint32) (err error)
   465  //sys	Mknod(path string, mode uint32, dev int) (err error)
   466  //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
   467  //sys	Open(path string, mode int, perm uint32) (fd int, err error)
   468  //sys	Pathconf(path string, name int) (val int, err error)
   469  //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
   470  //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
   471  //sys	read(fd int, p []byte) (n int, err error)
   472  //sys	Readlink(path string, buf []byte) (n int, err error)
   473  //sys	Rename(from string, to string) (err error)
   474  //sys	Rmdir(path string) (err error)
   475  //sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
   476  //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = libsendfile.sendfile
   477  //sysnb	Setegid(egid int) (err error)
   478  //sysnb	Seteuid(euid int) (err error)
   479  //sysnb	Setgid(gid int) (err error)
   480  //sysnb	Setpgid(pid int, pgid int) (err error)
   481  //sys	Setpriority(which int, who int, prio int) (err error)
   482  //sysnb	Setregid(rgid int, egid int) (err error)
   483  //sysnb	Setreuid(ruid int, euid int) (err error)
   484  //sysnb	Setrlimit(which int, lim *Rlimit) (err error)
   485  //sysnb	Setsid() (pid int, err error)
   486  //sysnb	Setuid(uid int) (err error)
   487  //sys	Shutdown(s int, how int) (err error) = libsocket.shutdown
   488  //sys	Stat(path string, stat *Stat_t) (err error)
   489  //sys	Symlink(path string, link string) (err error)
   490  //sys	Sync() (err error)
   491  //sys	Truncate(path string, length int64) (err error)
   492  //sys	Fsync(fd int) (err error)
   493  //sys	Ftruncate(fd int, length int64) (err error)
   494  //sys	Umask(newmask int) (oldmask int)
   495  //sys	Unlink(path string) (err error)
   496  //sys	Utimes(path string, times *[2]Timeval) (err error)
   497  //sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.bind
   498  //sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.connect
   499  //sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
   500  //sys	munmap(addr uintptr, length uintptr) (err error)
   501  //sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.sendto
   502  //sys	socket(domain int, typ int, proto int) (fd int, err error) = libsocket.socket
   503  //sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.socketpair
   504  //sys	write(fd int, p []byte) (n int, err error)
   505  //sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.getsockopt
   506  //sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername
   507  //sys	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname
   508  //sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt
   509  //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom
   510  //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.recvmsg
   511  
   512  func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
   513  	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
   514  	n = int(r0)
   515  	if e1 != 0 {
   516  		err = e1
   517  	}
   518  	return
   519  }
   520  
   521  func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
   522  	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_write)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
   523  	n = int(r0)
   524  	if e1 != 0 {
   525  		err = e1
   526  	}
   527  	return
   528  }