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