Source file 
src/syscall/syscall_solaris.go
     1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  
     9  
    10  
    11  
    12  
    13  package syscall
    14  
    15  import "unsafe"
    16  
    17  const _F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
    18  
    19  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    20  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    21  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    22  func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    23  
    24  
    25  func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    26  func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    27  
    28  type SockaddrDatalink struct {
    29  	Family uint16
    30  	Index  uint16
    31  	Type   uint8
    32  	Nlen   uint8
    33  	Alen   uint8
    34  	Slen   uint8
    35  	Data   [244]int8
    36  	raw    RawSockaddrDatalink
    37  }
    38  
    39  func direntIno(buf []byte) (uint64, bool) {
    40  	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
    41  }
    42  
    43  func direntReclen(buf []byte) (uint64, bool) {
    44  	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
    45  }
    46  
    47  func direntNamlen(buf []byte) (uint64, bool) {
    48  	reclen, ok := direntReclen(buf)
    49  	if !ok {
    50  		return 0, false
    51  	}
    52  	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
    53  }
    54  
    55  func Pipe(p []int) (err error) {
    56  	return Pipe2(p, 0)
    57  }
    58  
    59  
    60  
    61  func Pipe2(p []int, flags int) error {
    62  	if len(p) != 2 {
    63  		return EINVAL
    64  	}
    65  	var pp [2]_C_int
    66  	err := pipe2(&pp, flags)
    67  	if err == nil {
    68  		p[0] = int(pp[0])
    69  		p[1] = int(pp[1])
    70  	}
    71  	return err
    72  }
    73  
    74  
    75  
    76  func Accept4(fd int, flags int) (int, Sockaddr, error) {
    77  	var rsa RawSockaddrAny
    78  	var addrlen _Socklen = SizeofSockaddrAny
    79  	nfd, err := accept4(fd, &rsa, &addrlen, flags)
    80  	if err != nil {
    81  		return 0, nil, err
    82  	}
    83  	if addrlen > SizeofSockaddrAny {
    84  		panic("RawSockaddrAny too small")
    85  	}
    86  	sa, err := anyToSockaddr(&rsa)
    87  	if err != nil {
    88  		Close(nfd)
    89  		return 0, nil, err
    90  	}
    91  	return nfd, sa, nil
    92  }
    93  
    94  func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
    95  	if sa.Port < 0 || sa.Port > 0xFFFF {
    96  		return nil, 0, EINVAL
    97  	}
    98  	sa.raw.Family = AF_INET
    99  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
   100  	p[0] = byte(sa.Port >> 8)
   101  	p[1] = byte(sa.Port)
   102  	sa.raw.Addr = sa.Addr
   103  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
   104  }
   105  
   106  func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
   107  	if sa.Port < 0 || sa.Port > 0xFFFF {
   108  		return nil, 0, EINVAL
   109  	}
   110  	sa.raw.Family = AF_INET6
   111  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
   112  	p[0] = byte(sa.Port >> 8)
   113  	p[1] = byte(sa.Port)
   114  	sa.raw.Scope_id = sa.ZoneId
   115  	sa.raw.Addr = sa.Addr
   116  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
   117  }
   118  
   119  func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
   120  	name := sa.Name
   121  	n := len(name)
   122  	if n >= len(sa.raw.Path) {
   123  		return nil, 0, EINVAL
   124  	}
   125  	sa.raw.Family = AF_UNIX
   126  	for i := 0; i < n; i++ {
   127  		sa.raw.Path[i] = int8(name[i])
   128  	}
   129  	
   130  	sl := _Socklen(2)
   131  	if n > 0 {
   132  		sl += _Socklen(n) + 1
   133  	}
   134  	if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
   135  		
   136  		sa.raw.Path[0] = 0
   137  		
   138  		sl--
   139  	}
   140  
   141  	return unsafe.Pointer(&sa.raw), sl, nil
   142  }
   143  
   144  func Getsockname(fd int) (sa Sockaddr, err error) {
   145  	var rsa RawSockaddrAny
   146  	var len _Socklen = SizeofSockaddrAny
   147  	if err = getsockname(fd, &rsa, &len); err != nil {
   148  		return
   149  	}
   150  	return anyToSockaddr(&rsa)
   151  }
   152  
   153  const ImplementsGetwd = true
   154  
   155  
   156  
   157  func Getwd() (wd string, err error) {
   158  	var buf [PathMax]byte
   159  	
   160  	_, err = Getcwd(buf[0:])
   161  	if err != nil {
   162  		return "", err
   163  	}
   164  	n := clen(buf[:])
   165  	if n < 1 {
   166  		return "", EINVAL
   167  	}
   168  	return string(buf[:n]), nil
   169  }
   170  
   171  
   174  
   175  
   176  
   177  
   178  func Getgroups() (gids []int, err error) {
   179  	n, err := getgroups(0, nil)
   180  	if err != nil {
   181  		return nil, err
   182  	}
   183  	if n == 0 {
   184  		return nil, nil
   185  	}
   186  
   187  	
   188  	if n < 0 || n > 1000 {
   189  		return nil, EINVAL
   190  	}
   191  
   192  	a := make([]_Gid_t, n)
   193  	n, err = getgroups(n, &a[0])
   194  	if err != nil {
   195  		return nil, err
   196  	}
   197  	gids = make([]int, n)
   198  	for i, v := range a[0:n] {
   199  		gids[i] = int(v)
   200  	}
   201  	return
   202  }
   203  
   204  func Setgroups(gids []int) (err error) {
   205  	if len(gids) == 0 {
   206  		return setgroups(0, nil)
   207  	}
   208  
   209  	a := make([]_Gid_t, len(gids))
   210  	for i, v := range gids {
   211  		a[i] = _Gid_t(v)
   212  	}
   213  	return setgroups(len(a), &a[0])
   214  }
   215  
   216  func ReadDirent(fd int, buf []byte) (n int, err error) {
   217  	
   218  	
   219  	return Getdents(fd, buf, new(uintptr))
   220  }
   221  
   222  
   223  
   224  
   225  
   226  
   227  
   228  type WaitStatus uint32
   229  
   230  const (
   231  	mask  = 0x7F
   232  	core  = 0x80
   233  	shift = 8
   234  
   235  	exited  = 0
   236  	stopped = 0x7F
   237  )
   238  
   239  func (w WaitStatus) Exited() bool { return w&mask == exited }
   240  
   241  func (w WaitStatus) ExitStatus() int {
   242  	if w&mask != exited {
   243  		return -1
   244  	}
   245  	return int(w >> shift)
   246  }
   247  
   248  func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
   249  
   250  func (w WaitStatus) Signal() Signal {
   251  	sig := Signal(w & mask)
   252  	if sig == stopped || sig == 0 {
   253  		return -1
   254  	}
   255  	return sig
   256  }
   257  
   258  func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
   259  
   260  func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
   261  
   262  func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
   263  
   264  func (w WaitStatus) StopSignal() Signal {
   265  	if !w.Stopped() {
   266  		return -1
   267  	}
   268  	return Signal(w>>shift) & 0xFF
   269  }
   270  
   271  func (w WaitStatus) TrapCause() int { return -1 }
   272  
   273  func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr)
   274  
   275  func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
   276  	r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage)
   277  	if e1 != 0 {
   278  		err = Errno(e1)
   279  	}
   280  	return int(r0), err
   281  }
   282  
   283  func gethostname() (name string, err uintptr)
   284  
   285  func Gethostname() (name string, err error) {
   286  	name, e1 := gethostname()
   287  	if e1 != 0 {
   288  		err = Errno(e1)
   289  	}
   290  	return name, err
   291  }
   292  
   293  func UtimesNano(path string, ts []Timespec) error {
   294  	if len(ts) != 2 {
   295  		return EINVAL
   296  	}
   297  	return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
   298  }
   299  
   300  
   301  
   302  
   303  func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
   304  	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
   305  	if e1 != 0 {
   306  		return e1
   307  	}
   308  	return nil
   309  }
   310  
   311  func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
   312  	switch rsa.Addr.Family {
   313  	case AF_UNIX:
   314  		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
   315  		sa := new(SockaddrUnix)
   316  		
   317  		
   318  		
   319  		
   320  		
   321  		n := 0
   322  		for n < len(pp.Path) && pp.Path[n] != 0 {
   323  			n++
   324  		}
   325  		sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
   326  		return sa, nil
   327  
   328  	case AF_INET:
   329  		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
   330  		sa := new(SockaddrInet4)
   331  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   332  		sa.Port = int(p[0])<<8 + int(p[1])
   333  		sa.Addr = pp.Addr
   334  		return sa, nil
   335  
   336  	case AF_INET6:
   337  		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
   338  		sa := new(SockaddrInet6)
   339  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   340  		sa.Port = int(p[0])<<8 + int(p[1])
   341  		sa.ZoneId = pp.Scope_id
   342  		sa.Addr = pp.Addr
   343  		return sa, nil
   344  	}
   345  	return nil, EAFNOSUPPORT
   346  }
   347  
   348  
   349  
   350  func Accept(fd int) (nfd int, sa Sockaddr, err error) {
   351  	var rsa RawSockaddrAny
   352  	var len _Socklen = SizeofSockaddrAny
   353  	nfd, err = accept(fd, &rsa, &len)
   354  	if err != nil {
   355  		return
   356  	}
   357  	sa, err = anyToSockaddr(&rsa)
   358  	if err != nil {
   359  		Close(nfd)
   360  		nfd = 0
   361  	}
   362  	return
   363  }
   364  
   365  func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
   366  	var msg Msghdr
   367  	msg.Name = (*byte)(unsafe.Pointer(rsa))
   368  	msg.Namelen = uint32(SizeofSockaddrAny)
   369  	var iov Iovec
   370  	if len(p) > 0 {
   371  		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
   372  		iov.SetLen(len(p))
   373  	}
   374  	var dummy int8
   375  	if len(oob) > 0 {
   376  		
   377  		if len(p) == 0 {
   378  			iov.Base = &dummy
   379  			iov.SetLen(1)
   380  		}
   381  		msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
   382  		msg.Accrightslen = int32(len(oob))
   383  	}
   384  	msg.Iov = &iov
   385  	msg.Iovlen = 1
   386  	if n, err = recvmsg(fd, &msg, flags); err != nil {
   387  		return
   388  	}
   389  	oobn = int(msg.Accrightslen)
   390  	return
   391  }
   392  
   393  
   394  
   395  func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
   396  	var msg Msghdr
   397  	msg.Name = (*byte)(unsafe.Pointer(ptr))
   398  	msg.Namelen = uint32(salen)
   399  	var iov Iovec
   400  	if len(p) > 0 {
   401  		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
   402  		iov.SetLen(len(p))
   403  	}
   404  	var dummy int8
   405  	if len(oob) > 0 {
   406  		
   407  		if len(p) == 0 {
   408  			iov.Base = &dummy
   409  			iov.SetLen(1)
   410  		}
   411  		msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
   412  		msg.Accrightslen = int32(len(oob))
   413  	}
   414  	msg.Iov = &iov
   415  	msg.Iovlen = 1
   416  	if n, err = sendmsg(fd, &msg, flags); err != nil {
   417  		return 0, err
   418  	}
   419  	if len(oob) > 0 && len(p) == 0 {
   420  		n = 0
   421  	}
   422  	return n, nil
   423  }
   424  
   425  
   428  
   429  
   430  
   431  
   432  
   433  
   434  
   435  
   436  
   437  
   438  
   439  
   440  
   441  
   442  
   443  
   444  
   445  
   446  
   447  
   448  
   449  
   450  
   451  
   452  
   453  
   454  
   455  
   456  
   457  
   458  
   459  
   460  
   461  
   462  
   463  
   464  
   465  
   466  
   467  
   468  
   469  
   470  
   471  
   472  
   473  
   474  
   475  
   476  
   477  
   478  
   479  
   480  
   481  
   482  
   483  
   484  
   485  
   486  
   487  
   488  
   489  
   490  
   491  
   492  
   493  
   494  
   495  
   496  
   497  
   498  
   499  
   500  
   501  
   502  
   503  
   504  
   505  
   506  
   507  
   508  func Getexecname() (path string, err error) {
   509  	ptr, err := getexecname()
   510  	if err != nil {
   511  		return "", err
   512  	}
   513  	bytes := (*[1 << 29]byte)(ptr)[:]
   514  	for i, b := range bytes {
   515  		if b == 0 {
   516  			return string(bytes[:i]), nil
   517  		}
   518  	}
   519  	panic("unreachable")
   520  }
   521  
   522  func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
   523  	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
   524  	n = int(r0)
   525  	if e1 != 0 {
   526  		err = e1
   527  	}
   528  	return
   529  }
   530  
   531  var mapper = &mmapper{
   532  	active: make(map[*byte][]byte),
   533  	mmap:   mmap,
   534  	munmap: munmap,
   535  }
   536  
   537  func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
   538  	return mapper.Mmap(fd, offset, length, prot, flags)
   539  }
   540  
   541  func Munmap(b []byte) (err error) {
   542  	return mapper.Munmap(b)
   543  }
   544  
   545  func Utimes(path string, tv []Timeval) error {
   546  	if len(tv) != 2 {
   547  		return EINVAL
   548  	}
   549  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   550  }
   551  
View as plain text