github.com/afumu/libc@v0.0.6/libc_freebsd.go (about)

     1  // Copyright 2020 The Libc 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 libc // import "github.com/afumu/libc"
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  	"os"
    11  	"os/exec"
    12  	"path/filepath"
    13  	"runtime"
    14  	"runtime/debug"
    15  	"strings"
    16  	"syscall"
    17  	gotime "time"
    18  	"unicode"
    19  	"unsafe"
    20  
    21  	"github.com/afumu/libc/errno"
    22  	"github.com/afumu/libc/fcntl"
    23  	"github.com/afumu/libc/fts"
    24  	gonetdb "github.com/afumu/libc/honnef.co/go/netdb"
    25  	"github.com/afumu/libc/langinfo"
    26  	"github.com/afumu/libc/limits"
    27  	"github.com/afumu/libc/netdb"
    28  	"github.com/afumu/libc/netinet/in"
    29  	"github.com/afumu/libc/pthread"
    30  	"github.com/afumu/libc/signal"
    31  	"github.com/afumu/libc/stdio"
    32  	"github.com/afumu/libc/sys/socket"
    33  	"github.com/afumu/libc/sys/stat"
    34  	"github.com/afumu/libc/sys/types"
    35  	"github.com/afumu/libc/termios"
    36  	"github.com/afumu/libc/time"
    37  	"github.com/afumu/libc/unistd"
    38  	"github.com/afumu/libc/uuid"
    39  	guuid "github.com/google/uuid"
    40  	"golang.org/x/sys/unix"
    41  )
    42  
    43  var (
    44  	in6_addr_any in.In6_addr
    45  )
    46  
    47  // // Keep these outside of the var block otherwise go generate will miss them.
    48  var X__stderrp = Xstdout
    49  var X__stdinp = Xstdin
    50  var X__stdoutp = Xstdout
    51  
    52  // include/stdio.h:486:extern int __isthreaded;
    53  var X__isthreaded int32
    54  
    55  // lib/libc/locale/mblocal.h:62:	int __mb_sb_limit;
    56  var X__mb_sb_limit int32 = 128 // UTF-8
    57  
    58  // include/runetype.h:94:extern _Thread_local const _RuneLocale *_ThreadRuneLocale;
    59  var X_ThreadRuneLocale uintptr //TODO initialize and implement _Thread_local semantics.
    60  
    61  // include/xlocale/_ctype.h:54:_RuneLocale	*__runes_for_locale(locale_t, int*);
    62  func X__runes_for_locale(t *TLS, l locale_t, p uintptr) uintptr {
    63  	panic(todo(""))
    64  }
    65  
    66  type file uintptr
    67  
    68  func (f file) fd() int32      { return int32((*stdio.FILE)(unsafe.Pointer(f)).F_file) }
    69  func (f file) setFd(fd int32) { (*stdio.FILE)(unsafe.Pointer(f)).F_file = int16(fd) }
    70  
    71  func (f file) err() bool {
    72  	return (*stdio.FILE)(unsafe.Pointer(f)).F_flags&1 != 0
    73  }
    74  
    75  func (f file) setErr() {
    76  	(*stdio.FILE)(unsafe.Pointer(f)).F_flags |= 1
    77  }
    78  
    79  func (f file) close(t *TLS) int32 {
    80  	r := Xclose(t, f.fd())
    81  	Xfree(t, uintptr(f))
    82  	if r < 0 {
    83  		return stdio.EOF
    84  	}
    85  
    86  	return 0
    87  }
    88  
    89  func newFile(t *TLS, fd int32) uintptr {
    90  	p := Xcalloc(t, 1, types.Size_t(unsafe.Sizeof(stdio.FILE{})))
    91  	if p == 0 {
    92  		return 0
    93  	}
    94  	file(p).setFd(fd)
    95  	return p
    96  }
    97  
    98  func fwrite(fd int32, b []byte) (int, error) {
    99  	if fd == unistd.STDOUT_FILENO {
   100  		return write(b)
   101  	}
   102  
   103  	// if dmesgs {
   104  	// 	dmesg("%v: fd %v: %s", origin(1), fd, b)
   105  	// }
   106  	return unix.Write(int(fd), b) //TODO use Xwrite
   107  }
   108  
   109  // unsigned long	___runetype(__ct_rune_t) __pure;
   110  func X___runetype(t *TLS, x types.X__ct_rune_t) ulong {
   111  	panic(todo(""))
   112  }
   113  
   114  // int fprintf(FILE *stream, const char *format, ...);
   115  func Xfprintf(t *TLS, stream, format, args uintptr) int32 {
   116  	n, _ := fwrite(int32((*stdio.FILE)(unsafe.Pointer(stream)).F_file), printf(format, args))
   117  	return int32(n)
   118  }
   119  
   120  // int usleep(useconds_t usec);
   121  func Xusleep(t *TLS, usec types.X__useconds_t) int32 {
   122  	gotime.Sleep(gotime.Microsecond * gotime.Duration(usec))
   123  	return 0
   124  }
   125  
   126  // int getrusage(int who, struct rusage *usage);
   127  func Xgetrusage(t *TLS, who int32, usage uintptr) int32 {
   128  	if _, _, err := unix.Syscall(unix.SYS_GETRUSAGE, uintptr(who), usage, 0); err != 0 {
   129  		t.setErrno(err)
   130  		return -1
   131  	}
   132  
   133  	return 0
   134  }
   135  
   136  // int fgetc(FILE *stream);
   137  func Xfgetc(t *TLS, stream uintptr) int32 {
   138  	fd := int((*stdio.FILE)(unsafe.Pointer(stream)).F_file)
   139  	var buf [1]byte
   140  	if n, _ := unix.Read(fd, buf[:]); n != 0 {
   141  		return int32(buf[0])
   142  	}
   143  
   144  	return stdio.EOF
   145  }
   146  
   147  // int lstat(const char *pathname, struct stat *statbuf);
   148  func Xlstat(t *TLS, pathname, statbuf uintptr) int32 {
   149  	return Xlstat64(t, pathname, statbuf)
   150  }
   151  
   152  // int stat(const char *pathname, struct stat *statbuf);
   153  func Xstat(t *TLS, pathname, statbuf uintptr) int32 {
   154  	return Xstat64(t, pathname, statbuf)
   155  }
   156  
   157  // int chdir(const char *path);
   158  func Xchdir(t *TLS, path uintptr) int32 {
   159  	if _, _, err := unix.Syscall(unix.SYS_CHDIR, path, 0, 0); err != 0 {
   160  		t.setErrno(err)
   161  		return -1
   162  	}
   163  
   164  	// if dmesgs {
   165  	// 	dmesg("%v: %q: ok", origin(1), GoString(path))
   166  	// }
   167  	return 0
   168  }
   169  
   170  var localtime time.Tm
   171  
   172  // struct tm *localtime(const time_t *timep);
   173  func Xlocaltime(_ *TLS, timep uintptr) uintptr {
   174  	loc := getLocalLocation()
   175  	ut := *(*time.Time_t)(unsafe.Pointer(timep))
   176  	t := gotime.Unix(int64(ut), 0).In(loc)
   177  	localtime.Ftm_sec = int32(t.Second())
   178  	localtime.Ftm_min = int32(t.Minute())
   179  	localtime.Ftm_hour = int32(t.Hour())
   180  	localtime.Ftm_mday = int32(t.Day())
   181  	localtime.Ftm_mon = int32(t.Month() - 1)
   182  	localtime.Ftm_year = int32(t.Year() - 1900)
   183  	localtime.Ftm_wday = int32(t.Weekday())
   184  	localtime.Ftm_yday = int32(t.YearDay())
   185  	localtime.Ftm_isdst = Bool32(isTimeDST(t))
   186  	return uintptr(unsafe.Pointer(&localtime))
   187  }
   188  
   189  // struct tm *localtime_r(const time_t *timep, struct tm *result);
   190  func Xlocaltime_r(_ *TLS, timep, result uintptr) uintptr {
   191  	loc := getLocalLocation()
   192  	ut := *(*unix.Time_t)(unsafe.Pointer(timep))
   193  	t := gotime.Unix(int64(ut), 0).In(loc)
   194  	(*time.Tm)(unsafe.Pointer(result)).Ftm_sec = int32(t.Second())
   195  	(*time.Tm)(unsafe.Pointer(result)).Ftm_min = int32(t.Minute())
   196  	(*time.Tm)(unsafe.Pointer(result)).Ftm_hour = int32(t.Hour())
   197  	(*time.Tm)(unsafe.Pointer(result)).Ftm_mday = int32(t.Day())
   198  	(*time.Tm)(unsafe.Pointer(result)).Ftm_mon = int32(t.Month() - 1)
   199  	(*time.Tm)(unsafe.Pointer(result)).Ftm_year = int32(t.Year() - 1900)
   200  	(*time.Tm)(unsafe.Pointer(result)).Ftm_wday = int32(t.Weekday())
   201  	(*time.Tm)(unsafe.Pointer(result)).Ftm_yday = int32(t.YearDay())
   202  	(*time.Tm)(unsafe.Pointer(result)).Ftm_isdst = Bool32(isTimeDST(t))
   203  	return result
   204  }
   205  
   206  // int open(const char *pathname, int flags, ...);
   207  func Xopen(t *TLS, pathname uintptr, flags int32, args uintptr) int32 {
   208  	return Xopen64(t, pathname, flags, args)
   209  }
   210  
   211  // int open(const char *pathname, int flags, ...);
   212  func Xopen64(t *TLS, pathname uintptr, flags int32, args uintptr) int32 {
   213  	var mode types.Mode_t
   214  	if args != 0 {
   215  		mode = (types.Mode_t)(VaUint32(&args))
   216  	}
   217  	fdcwd := fcntl.AT_FDCWD
   218  	n, _, err := unix.Syscall6(unix.SYS_OPENAT, uintptr(fdcwd), pathname, uintptr(flags), uintptr(mode), 0, 0)
   219  	if err != 0 {
   220  		// if dmesgs {
   221  		// 	dmesg("%v: %q %#x: %v", origin(1), GoString(pathname), flags, err)
   222  		// }
   223  		t.setErrno(err)
   224  		return -1
   225  	}
   226  
   227  	// if dmesgs {
   228  	// 	dmesg("%v: %q flags %#x mode %#o: fd %v", origin(1), GoString(pathname), flags, mode, n)
   229  	// }
   230  	return int32(n)
   231  }
   232  
   233  // off_t lseek(int fd, off_t offset, int whence);
   234  func Xlseek(t *TLS, fd int32, offset types.Off_t, whence int32) types.Off_t {
   235  	return types.Off_t(Xlseek64(t, fd, offset, whence))
   236  }
   237  
   238  func whenceStr(whence int32) string {
   239  	panic(todo(""))
   240  }
   241  
   242  var fsyncStatbuf stat.Stat
   243  
   244  // int fsync(int fd);
   245  func Xfsync(t *TLS, fd int32) int32 {
   246  	if noFsync {
   247  		// Simulate -DSQLITE_NO_SYNC for sqlite3 testfixture, see function full_sync in sqlite3.c
   248  		return Xfstat(t, fd, uintptr(unsafe.Pointer(&fsyncStatbuf)))
   249  	}
   250  
   251  	if _, _, err := unix.Syscall(unix.SYS_FSYNC, uintptr(fd), 0, 0); err != 0 {
   252  		t.setErrno(err)
   253  		return -1
   254  	}
   255  
   256  	// if dmesgs {
   257  	// 	dmesg("%v: %d: ok", origin(1), fd)
   258  	// }
   259  	return 0
   260  }
   261  
   262  // long sysconf(int name);
   263  func Xsysconf(t *TLS, name int32) long {
   264  	switch name {
   265  	case unistd.X_SC_PAGESIZE:
   266  		return long(unix.Getpagesize())
   267  	case unistd.X_SC_GETPW_R_SIZE_MAX:
   268  		return -1
   269  	case unistd.X_SC_GETGR_R_SIZE_MAX:
   270  		return -1
   271  	case unistd.X_SC_NPROCESSORS_ONLN:
   272  		return long(runtime.NumCPU())
   273  	}
   274  
   275  	panic(todo("", name))
   276  }
   277  
   278  // int close(int fd);
   279  func Xclose(t *TLS, fd int32) int32 {
   280  	if _, _, err := unix.Syscall(unix.SYS_CLOSE, uintptr(fd), 0, 0); err != 0 {
   281  		t.setErrno(err)
   282  		return -1
   283  	}
   284  
   285  	// if dmesgs {
   286  	// 	dmesg("%v: %d: ok", origin(1), fd)
   287  	// }
   288  	return 0
   289  }
   290  
   291  // char *getcwd(char *buf, size_t size);
   292  func Xgetcwd(t *TLS, buf uintptr, size types.Size_t) uintptr {
   293  	if _, err := unix.Getcwd((*RawMem)(unsafe.Pointer(buf))[:size:size]); err != nil {
   294  		if dmesgs {
   295  			dmesg("%v: %v FAIL", origin(1), err)
   296  		}
   297  		t.setErrno(err)
   298  		return 0
   299  	}
   300  
   301  	if dmesgs {
   302  		dmesg("%v: ok", origin(1))
   303  	}
   304  	return buf
   305  }
   306  
   307  // int fstat(int fd, struct stat *statbuf);
   308  func Xfstat(t *TLS, fd int32, statbuf uintptr) int32 {
   309  	return Xfstat64(t, fd, statbuf)
   310  }
   311  
   312  // int ftruncate(int fd, off_t length);
   313  func Xftruncate(t *TLS, fd int32, length types.Off_t) int32 {
   314  	if err := unix.Ftruncate(int(fd), int64(length)); err != nil {
   315  		if dmesgs {
   316  			dmesg("%v: fd %d: %v FAIL", origin(1), fd, err)
   317  		}
   318  		t.setErrno(err)
   319  		return -1
   320  	}
   321  
   322  	if dmesgs {
   323  		dmesg("%v: %d %#x: ok", origin(1), fd, length)
   324  	}
   325  	return 0
   326  }
   327  
   328  // int fcntl(int fd, int cmd, ... /* arg */ );
   329  func Xfcntl(t *TLS, fd, cmd int32, args uintptr) int32 {
   330  	return Xfcntl64(t, fd, cmd, args)
   331  }
   332  
   333  // ssize_t read(int fd, void *buf, size_t count);
   334  func Xread(t *TLS, fd int32, buf uintptr, count types.Size_t) types.Ssize_t {
   335  	n, _, err := unix.Syscall(unix.SYS_READ, uintptr(fd), buf, uintptr(count))
   336  	if err != 0 {
   337  		t.setErrno(err)
   338  		return -1
   339  	}
   340  
   341  	// if dmesgs {
   342  	// 	// dmesg("%v: %d %#x: %#x\n%s", origin(1), fd, count, n, hex.Dump(GoBytes(buf, int(n))))
   343  	// 	dmesg("%v: %d %#x: %#x", origin(1), fd, count, n)
   344  	// }
   345  	return types.Ssize_t(n)
   346  }
   347  
   348  // ssize_t write(int fd, const void *buf, size_t count);
   349  func Xwrite(t *TLS, fd int32, buf uintptr, count types.Size_t) types.Ssize_t {
   350  	const retry = 5
   351  	var err syscall.Errno
   352  	for i := 0; i < retry; i++ {
   353  		var n uintptr
   354  		switch n, _, err = unix.Syscall(unix.SYS_WRITE, uintptr(fd), buf, uintptr(count)); err {
   355  		case 0:
   356  			// if dmesgs {
   357  			// 	// dmesg("%v: %d %#x: %#x\n%s", origin(1), fd, count, n, hex.Dump(GoBytes(buf, int(n))))
   358  			// 	dmesg("%v: %d %#x: %#x", origin(1), fd, count, n)
   359  			// }
   360  			return types.Ssize_t(n)
   361  		case errno.EAGAIN:
   362  			// nop
   363  		}
   364  	}
   365  
   366  	// if dmesgs {
   367  	// 	dmesg("%v: fd %v, count %#x: %v", origin(1), fd, count, err)
   368  	// }
   369  	t.setErrno(err)
   370  	return -1
   371  }
   372  
   373  // int fchmod(int fd, mode_t mode);
   374  func Xfchmod(t *TLS, fd int32, mode types.Mode_t) int32 {
   375  	if _, _, err := unix.Syscall(unix.SYS_FCHMOD, uintptr(fd), uintptr(mode), 0); err != 0 {
   376  		t.setErrno(err)
   377  		return -1
   378  	}
   379  
   380  	// if dmesgs {
   381  	// 	dmesg("%v: %d %#o: ok", origin(1), fd, mode)
   382  	// }
   383  	return 0
   384  }
   385  
   386  // int fchown(int fd, uid_t owner, gid_t group);
   387  func Xfchown(t *TLS, fd int32, owner types.Uid_t, group types.Gid_t) int32 {
   388  	if _, _, err := unix.Syscall(unix.SYS_FCHOWN, uintptr(fd), uintptr(owner), uintptr(group)); err != 0 {
   389  		t.setErrno(err)
   390  		return -1
   391  	}
   392  
   393  	return 0
   394  }
   395  
   396  // uid_t geteuid(void);
   397  func Xgeteuid(t *TLS) types.Uid_t {
   398  	n, _, _ := unix.Syscall(unix.SYS_GETEUID, 0, 0, 0)
   399  	return types.Uid_t(n)
   400  }
   401  
   402  // int munmap(void *addr, size_t length);
   403  func Xmunmap(t *TLS, addr uintptr, length types.Size_t) int32 {
   404  	if _, _, err := unix.Syscall(unix.SYS_MUNMAP, addr, uintptr(length), 0); err != 0 {
   405  		t.setErrno(err)
   406  		return -1
   407  	}
   408  
   409  	return 0
   410  }
   411  
   412  // int gettimeofday(struct timeval *tv, struct timezone *tz);
   413  func Xgettimeofday(t *TLS, tv, tz uintptr) int32 {
   414  	if tz != 0 {
   415  		panic(todo(""))
   416  	}
   417  
   418  	var tvs unix.Timeval
   419  	err := unix.Gettimeofday(&tvs)
   420  	if err != nil {
   421  		t.setErrno(err)
   422  		return -1
   423  	}
   424  
   425  	*(*unix.Timeval)(unsafe.Pointer(tv)) = tvs
   426  	return 0
   427  }
   428  
   429  // int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
   430  func Xgetsockopt(t *TLS, sockfd, level, optname int32, optval, optlen uintptr) int32 {
   431  	if _, _, err := unix.Syscall6(unix.SYS_GETSOCKOPT, uintptr(sockfd), uintptr(level), uintptr(optname), optval, optlen, 0); err != 0 {
   432  		t.setErrno(err)
   433  		return -1
   434  	}
   435  
   436  	return 0
   437  }
   438  
   439  // int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
   440  func Xsetsockopt(t *TLS, sockfd, level, optname int32, optval uintptr, optlen socket.Socklen_t) int32 {
   441  	if _, _, err := unix.Syscall6(unix.SYS_SETSOCKOPT, uintptr(sockfd), uintptr(level), uintptr(optname), optval, uintptr(optlen), 0); err != 0 {
   442  		t.setErrno(err)
   443  		return -1
   444  	}
   445  
   446  	return 0
   447  }
   448  
   449  // int ioctl(int fd, unsigned long request, ...);
   450  func Xioctl(t *TLS, fd int32, request ulong, va uintptr) int32 {
   451  	var argp uintptr
   452  	if va != 0 {
   453  		argp = VaUintptr(&va)
   454  	}
   455  	n, _, err := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(request), argp)
   456  	if err != 0 {
   457  		t.setErrno(err)
   458  		return -1
   459  	}
   460  
   461  	return int32(n)
   462  }
   463  
   464  // int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
   465  func Xgetsockname(t *TLS, sockfd int32, addr, addrlen uintptr) int32 {
   466  	if _, _, err := unix.Syscall(unix.SYS_GETSOCKNAME, uintptr(sockfd), addr, addrlen); err != 0 {
   467  		// if dmesgs {
   468  		// 	dmesg("%v: fd %v: %v", origin(1), sockfd, err)
   469  		// }
   470  		t.setErrno(err)
   471  		return -1
   472  	}
   473  
   474  	return 0
   475  }
   476  
   477  // int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
   478  func Xselect(t *TLS, nfds int32, readfds, writefds, exceptfds, timeout uintptr) int32 {
   479  	n, err := unix.Select(
   480  		int(nfds),
   481  		(*unix.FdSet)(unsafe.Pointer(readfds)),
   482  		(*unix.FdSet)(unsafe.Pointer(writefds)),
   483  		(*unix.FdSet)(unsafe.Pointer(exceptfds)),
   484  		(*unix.Timeval)(unsafe.Pointer(timeout)),
   485  	)
   486  	if err != nil {
   487  		t.setErrno(err)
   488  		return -1
   489  	}
   490  
   491  	return int32(n)
   492  }
   493  
   494  // int mkfifo(const char *pathname, mode_t mode);
   495  func Xmkfifo(t *TLS, pathname uintptr, mode types.Mode_t) int32 {
   496  	panic(todo(""))
   497  }
   498  
   499  // mode_t umask(mode_t mask);
   500  func Xumask(t *TLS, mask types.Mode_t) types.Mode_t {
   501  	n, _, _ := unix.Syscall(unix.SYS_UMASK, uintptr(mask), 0, 0)
   502  	return types.Mode_t(n)
   503  }
   504  
   505  // int execvp(const char *file, char *const argv[]);
   506  func Xexecvp(t *TLS, file, argv uintptr) int32 {
   507  	if _, _, err := unix.Syscall(unix.SYS_EXECVE, file, argv, Environ()); err != 0 {
   508  		t.setErrno(err)
   509  		return -1
   510  	}
   511  
   512  	return 0
   513  }
   514  
   515  // pid_t waitpid(pid_t pid, int *wstatus, int options);
   516  func Xwaitpid(t *TLS, pid types.Pid_t, wstatus uintptr, optname int32) types.Pid_t {
   517  	n, _, err := unix.Syscall6(unix.SYS_WAIT4, uintptr(pid), wstatus, uintptr(optname), 0, 0, 0)
   518  	if err != 0 {
   519  		t.setErrno(err)
   520  		return -1
   521  	}
   522  
   523  	return types.Pid_t(n)
   524  }
   525  
   526  // int uname(struct utsname *buf);
   527  func Xuname(t *TLS, buf uintptr) int32 {
   528  	if err := unix.Uname((*unix.Utsname)(unsafe.Pointer(buf))); err != nil {
   529  		if dmesgs {
   530  			dmesg("%v: %v FAIL", origin(1), err)
   531  		}
   532  		t.setErrno(err)
   533  		return -1
   534  	}
   535  
   536  	if dmesgs {
   537  		dmesg("%v: ok", origin(1))
   538  	}
   539  	return 0
   540  }
   541  
   542  // ssize_t recv(int sockfd, void *buf, size_t len, int flags);
   543  func Xrecv(t *TLS, sockfd int32, buf uintptr, len types.Size_t, flags int32) types.Ssize_t {
   544  	n, _, err := unix.Syscall6(unix.SYS_RECVFROM, uintptr(sockfd), buf, uintptr(len), uintptr(flags), 0, 0)
   545  	if err != 0 {
   546  		t.setErrno(err)
   547  		return -1
   548  	}
   549  
   550  	return types.Ssize_t(n)
   551  }
   552  
   553  // ssize_t send(int sockfd, const void *buf, size_t len, int flags);
   554  func Xsend(t *TLS, sockfd int32, buf uintptr, len types.Size_t, flags int32) types.Ssize_t {
   555  	n, _, err := unix.Syscall6(unix.SYS_SENDTO, uintptr(sockfd), buf, uintptr(len), uintptr(flags), 0, 0)
   556  	if err != 0 {
   557  		t.setErrno(err)
   558  		return -1
   559  	}
   560  
   561  	return types.Ssize_t(n)
   562  }
   563  
   564  // int shutdown(int sockfd, int how);
   565  func Xshutdown(t *TLS, sockfd, how int32) int32 {
   566  	if _, _, err := unix.Syscall(unix.SYS_SHUTDOWN, uintptr(sockfd), uintptr(how), 0); err != 0 {
   567  		t.setErrno(err)
   568  		return -1
   569  	}
   570  
   571  	return 0
   572  }
   573  
   574  // int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
   575  func Xgetpeername(t *TLS, sockfd int32, addr uintptr, addrlen uintptr) int32 {
   576  	if _, _, err := unix.Syscall(unix.SYS_GETPEERNAME, uintptr(sockfd), addr, uintptr(addrlen)); err != 0 {
   577  		t.setErrno(err)
   578  		return -1
   579  	}
   580  
   581  	return 0
   582  }
   583  
   584  // int socket(int domain, int type, int protocol);
   585  func Xsocket(t *TLS, domain, type1, protocol int32) int32 {
   586  	n, _, err := unix.Syscall(unix.SYS_SOCKET, uintptr(domain), uintptr(type1), uintptr(protocol))
   587  	if err != 0 {
   588  		t.setErrno(err)
   589  		return -1
   590  	}
   591  
   592  	return int32(n)
   593  }
   594  
   595  // int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
   596  func Xbind(t *TLS, sockfd int32, addr uintptr, addrlen uint32) int32 {
   597  	n, _, err := unix.Syscall(unix.SYS_BIND, uintptr(sockfd), addr, uintptr(addrlen))
   598  	if err != 0 {
   599  		t.setErrno(err)
   600  		return -1
   601  	}
   602  
   603  	return int32(n)
   604  }
   605  
   606  // int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
   607  func Xconnect(t *TLS, sockfd int32, addr uintptr, addrlen uint32) int32 {
   608  	if _, _, err := unix.Syscall(unix.SYS_CONNECT, uintptr(sockfd), addr, uintptr(addrlen)); err != 0 {
   609  		t.setErrno(err)
   610  		return -1
   611  	}
   612  
   613  	return 0
   614  }
   615  
   616  // int listen(int sockfd, int backlog);
   617  func Xlisten(t *TLS, sockfd, backlog int32) int32 {
   618  	if _, _, err := unix.Syscall(unix.SYS_LISTEN, uintptr(sockfd), uintptr(backlog), 0); err != 0 {
   619  		t.setErrno(err)
   620  		return -1
   621  	}
   622  
   623  	return 0
   624  }
   625  
   626  // int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
   627  func Xaccept(t *TLS, sockfd int32, addr uintptr, addrlen uintptr) int32 {
   628  	n, _, err := unix.Syscall6(unix.SYS_ACCEPT4, uintptr(sockfd), addr, uintptr(addrlen), 0, 0, 0)
   629  	if err != 0 {
   630  		t.setErrno(err)
   631  		return -1
   632  	}
   633  
   634  	return int32(n)
   635  }
   636  
   637  // int getrlimit(int resource, struct rlimit *rlim);
   638  func Xgetrlimit(t *TLS, resource int32, rlim uintptr) int32 {
   639  	return Xgetrlimit64(t, resource, rlim)
   640  }
   641  
   642  // int setrlimit(int resource, const struct rlimit *rlim);
   643  func Xsetrlimit(t *TLS, resource int32, rlim uintptr) int32 {
   644  	return Xsetrlimit64(t, resource, rlim)
   645  }
   646  
   647  // int setrlimit(int resource, const struct rlimit *rlim);
   648  func Xsetrlimit64(t *TLS, resource int32, rlim uintptr) int32 {
   649  	if _, _, err := unix.Syscall(unix.SYS_SETRLIMIT, uintptr(resource), uintptr(rlim), 0); err != 0 {
   650  		t.setErrno(err)
   651  		return -1
   652  	}
   653  
   654  	return 0
   655  }
   656  
   657  // uid_t getuid(void);
   658  func Xgetuid(t *TLS) types.Uid_t {
   659  	return types.Uid_t(os.Getuid())
   660  }
   661  
   662  // pid_t getpid(void);
   663  func Xgetpid(t *TLS) int32 {
   664  	return int32(os.Getpid())
   665  }
   666  
   667  // int system(const char *command);
   668  func Xsystem(t *TLS, command uintptr) int32 {
   669  	s := GoString(command)
   670  	if command == 0 {
   671  		panic(todo(""))
   672  	}
   673  
   674  	cmd := exec.Command("sh", "-c", s)
   675  	cmd.Stdout = os.Stdout
   676  	cmd.Stderr = os.Stderr
   677  	err := cmd.Run()
   678  	if err != nil {
   679  		ps := err.(*exec.ExitError)
   680  		return int32(ps.ExitCode())
   681  	}
   682  
   683  	return 0
   684  }
   685  
   686  // int setvbuf(FILE *stream, char *buf, int mode, size_t size);
   687  func Xsetvbuf(t *TLS, stream, buf uintptr, mode int32, size types.Size_t) int32 {
   688  	return 0 //TODO
   689  }
   690  
   691  // int raise(int sig);
   692  func Xraise(t *TLS, sig int32) int32 {
   693  	panic(todo(""))
   694  }
   695  
   696  // int backtrace(void **buffer, int size);
   697  func Xbacktrace(t *TLS, buf uintptr, size int32) int32 {
   698  	panic(todo(""))
   699  }
   700  
   701  // void backtrace_symbols_fd(void *const *buffer, int size, int fd);
   702  func Xbacktrace_symbols_fd(t *TLS, buffer uintptr, size, fd int32) {
   703  	panic(todo(""))
   704  }
   705  
   706  // int fileno(FILE *stream);
   707  func Xfileno(t *TLS, stream uintptr) int32 {
   708  	panic(todo(""))
   709  }
   710  
   711  func newCFtsent(t *TLS, info int, path string, stat *unix.Stat_t, err syscall.Errno) uintptr {
   712  	p := Xcalloc(t, 1, types.Size_t(unsafe.Sizeof(fts.FTSENT{})))
   713  	if p == 0 {
   714  		panic("OOM")
   715  	}
   716  
   717  	*(*fts.FTSENT)(unsafe.Pointer(p)) = *newFtsent(t, info, path, stat, err)
   718  	return p
   719  }
   720  
   721  func ftsentClose(t *TLS, p uintptr) {
   722  	Xfree(t, (*fts.FTSENT)(unsafe.Pointer(p)).Ffts_path)
   723  	Xfree(t, (*fts.FTSENT)(unsafe.Pointer(p)).Ffts_statp)
   724  }
   725  
   726  type ftstream struct {
   727  	s []uintptr
   728  	x int
   729  }
   730  
   731  func (f *ftstream) close(t *TLS) {
   732  	for _, p := range f.s {
   733  		ftsentClose(t, p)
   734  		Xfree(t, p)
   735  	}
   736  	*f = ftstream{}
   737  }
   738  
   739  // FTS *fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **));
   740  func Xfts_open(t *TLS, path_argv uintptr, options int32, compar uintptr) uintptr {
   741  	return Xfts64_open(t, path_argv, options, compar)
   742  }
   743  
   744  // FTS *fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **));
   745  func Xfts64_open(t *TLS, path_argv uintptr, options int32, compar uintptr) uintptr {
   746  	f := &ftstream{}
   747  
   748  	var walk func(string)
   749  	walk = func(path string) {
   750  		var fi os.FileInfo
   751  		var err error
   752  		switch {
   753  		case options&fts.FTS_LOGICAL != 0:
   754  			fi, err = os.Stat(path)
   755  		case options&fts.FTS_PHYSICAL != 0:
   756  			fi, err = os.Lstat(path)
   757  		default:
   758  			panic(todo(""))
   759  		}
   760  
   761  		if err != nil {
   762  			return
   763  		}
   764  
   765  		var statp *unix.Stat_t
   766  		if options&fts.FTS_NOSTAT == 0 {
   767  			var stat unix.Stat_t
   768  			switch {
   769  			case options&fts.FTS_LOGICAL != 0:
   770  				if err := unix.Stat(path, &stat); err != nil {
   771  					panic(todo(""))
   772  				}
   773  			case options&fts.FTS_PHYSICAL != 0:
   774  				if err := unix.Lstat(path, &stat); err != nil {
   775  					panic(todo(""))
   776  				}
   777  			default:
   778  				panic(todo(""))
   779  			}
   780  
   781  			statp = &stat
   782  		}
   783  
   784  	out:
   785  		switch {
   786  		case fi.IsDir():
   787  			f.s = append(f.s, newCFtsent(t, fts.FTS_D, path, statp, 0))
   788  			g, err := os.Open(path)
   789  			switch x := err.(type) {
   790  			case nil:
   791  				// ok
   792  			case *os.PathError:
   793  				f.s = append(f.s, newCFtsent(t, fts.FTS_DNR, path, statp, errno.EACCES))
   794  				break out
   795  			default:
   796  				panic(todo("%q: %v %T", path, x, x))
   797  			}
   798  
   799  			names, err := g.Readdirnames(-1)
   800  			g.Close()
   801  			if err != nil {
   802  				panic(todo(""))
   803  			}
   804  
   805  			for _, name := range names {
   806  				walk(path + "/" + name)
   807  				if f == nil {
   808  					break out
   809  				}
   810  			}
   811  
   812  			f.s = append(f.s, newCFtsent(t, fts.FTS_DP, path, statp, 0))
   813  		default:
   814  			info := fts.FTS_F
   815  			if fi.Mode()&os.ModeSymlink != 0 {
   816  				info = fts.FTS_SL
   817  			}
   818  			switch {
   819  			case statp != nil:
   820  				f.s = append(f.s, newCFtsent(t, info, path, statp, 0))
   821  			case options&fts.FTS_NOSTAT != 0:
   822  				f.s = append(f.s, newCFtsent(t, fts.FTS_NSOK, path, nil, 0))
   823  			default:
   824  				panic(todo(""))
   825  			}
   826  		}
   827  	}
   828  
   829  	for {
   830  		p := *(*uintptr)(unsafe.Pointer(path_argv))
   831  		if p == 0 {
   832  			if f == nil {
   833  				return 0
   834  			}
   835  
   836  			if compar != 0 {
   837  				panic(todo(""))
   838  			}
   839  
   840  			return addObject(f)
   841  		}
   842  
   843  		walk(GoString(p))
   844  		path_argv += unsafe.Sizeof(uintptr(0))
   845  	}
   846  }
   847  
   848  // FTSENT *fts_read(FTS *ftsp);
   849  func Xfts_read(t *TLS, ftsp uintptr) uintptr {
   850  	return Xfts64_read(t, ftsp)
   851  }
   852  
   853  // FTSENT *fts_read(FTS *ftsp);
   854  func Xfts64_read(t *TLS, ftsp uintptr) uintptr {
   855  	f := getObject(ftsp).(*ftstream)
   856  	if f.x == len(f.s) {
   857  		t.setErrno(0)
   858  		return 0
   859  	}
   860  
   861  	r := f.s[f.x]
   862  	if e := (*fts.FTSENT)(unsafe.Pointer(r)).Ffts_errno; e != 0 {
   863  		t.setErrno(e)
   864  	}
   865  	f.x++
   866  	return r
   867  }
   868  
   869  // int fts_close(FTS *ftsp);
   870  func Xfts_close(t *TLS, ftsp uintptr) int32 {
   871  	return Xfts64_close(t, ftsp)
   872  }
   873  
   874  // int fts_close(FTS *ftsp);
   875  func Xfts64_close(t *TLS, ftsp uintptr) int32 {
   876  	getObject(ftsp).(*ftstream).close(t)
   877  	removeObject(ftsp)
   878  	return 0
   879  }
   880  
   881  // void tzset (void);
   882  func Xtzset(t *TLS) {
   883  	//TODO
   884  }
   885  
   886  var strerrorBuf [100]byte
   887  
   888  // char *strerror(int errnum);
   889  func Xstrerror(t *TLS, errnum int32) uintptr {
   890  	if dmesgs {
   891  		dmesg("%v: %v\n%s", origin(1), errnum, debug.Stack())
   892  	}
   893  	copy(strerrorBuf[:], fmt.Sprintf("strerror(%d)\x00", errnum))
   894  	return uintptr(unsafe.Pointer(&strerrorBuf[0]))
   895  }
   896  
   897  // void *dlopen(const char *filename, int flags);
   898  func Xdlopen(t *TLS, filename uintptr, flags int32) uintptr {
   899  	panic(todo(""))
   900  }
   901  
   902  // char *dlerror(void);
   903  func Xdlerror(t *TLS) uintptr {
   904  	panic(todo(""))
   905  }
   906  
   907  // int dlclose(void *handle);
   908  func Xdlclose(t *TLS, handle uintptr) int32 {
   909  	panic(todo(""))
   910  }
   911  
   912  // void *dlsym(void *handle, const char *symbol);
   913  func Xdlsym(t *TLS, handle, symbol uintptr) uintptr {
   914  	panic(todo(""))
   915  }
   916  
   917  // void perror(const char *s);
   918  func Xperror(t *TLS, s uintptr) {
   919  	panic(todo(""))
   920  }
   921  
   922  // int pclose(FILE *stream);
   923  func Xpclose(t *TLS, stream uintptr) int32 {
   924  	panic(todo(""))
   925  }
   926  
   927  var gai_strerrorBuf [100]byte
   928  
   929  // const char *gai_strerror(int errcode);
   930  func Xgai_strerror(t *TLS, errcode int32) uintptr {
   931  	copy(gai_strerrorBuf[:], fmt.Sprintf("gai error %d\x00", errcode))
   932  	return uintptr(unsafe.Pointer(&gai_strerrorBuf))
   933  }
   934  
   935  // int tcgetattr(int fd, struct termios *termios_p);
   936  func Xtcgetattr(t *TLS, fd int32, termios_p uintptr) int32 {
   937  	panic(todo(""))
   938  }
   939  
   940  // int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
   941  func Xtcsetattr(t *TLS, fd, optional_actions int32, termios_p uintptr) int32 {
   942  	panic(todo(""))
   943  }
   944  
   945  // speed_t cfgetospeed(const struct termios *termios_p);
   946  func Xcfgetospeed(t *TLS, termios_p uintptr) termios.Speed_t {
   947  	panic(todo(""))
   948  }
   949  
   950  // int cfsetospeed(struct termios *termios_p, speed_t speed);
   951  func Xcfsetospeed(t *TLS, termios_p uintptr, speed uint32) int32 {
   952  	panic(todo(""))
   953  }
   954  
   955  // int cfsetispeed(struct termios *termios_p, speed_t speed);
   956  func Xcfsetispeed(t *TLS, termios_p uintptr, speed uint32) int32 {
   957  	panic(todo(""))
   958  }
   959  
   960  // pid_t fork(void);
   961  func Xfork(t *TLS) int32 {
   962  	t.setErrno(errno.ENOSYS)
   963  	return -1
   964  }
   965  
   966  var emptyStr = [1]byte{}
   967  
   968  // char *setlocale(int category, const char *locale);
   969  func Xsetlocale(t *TLS, category int32, locale uintptr) uintptr {
   970  	return uintptr(unsafe.Pointer(&emptyStr)) //TODO
   971  }
   972  
   973  // char *nl_langinfo(nl_item item);
   974  func Xnl_langinfo(t *TLS, item langinfo.Nl_item) uintptr {
   975  	return uintptr(unsafe.Pointer(&emptyStr)) //TODO
   976  }
   977  
   978  // FILE *popen(const char *command, const char *type);
   979  func Xpopen(t *TLS, command, type1 uintptr) uintptr {
   980  	panic(todo(""))
   981  }
   982  
   983  // char *realpath(const char *path, char *resolved_path);
   984  func Xrealpath(t *TLS, path, resolved_path uintptr) uintptr {
   985  	s, err := filepath.EvalSymlinks(GoString(path))
   986  	if err != nil {
   987  		if os.IsNotExist(err) {
   988  			// if dmesgs {
   989  			// 	dmesg("%v: %q: %v", origin(1), GoString(path), err)
   990  			// }
   991  			t.setErrno(errno.ENOENT)
   992  			return 0
   993  		}
   994  
   995  		panic(todo("", err))
   996  	}
   997  
   998  	if resolved_path == 0 {
   999  		panic(todo(""))
  1000  	}
  1001  
  1002  	if len(s) >= limits.PATH_MAX {
  1003  		s = s[:limits.PATH_MAX-1]
  1004  	}
  1005  
  1006  	copy((*RawMem)(unsafe.Pointer(resolved_path))[:len(s):len(s)], s)
  1007  	(*RawMem)(unsafe.Pointer(resolved_path))[len(s)] = 0
  1008  	return resolved_path
  1009  }
  1010  
  1011  // struct tm *gmtime_r(const time_t *timep, struct tm *result);
  1012  func Xgmtime_r(t *TLS, timep, result uintptr) uintptr {
  1013  	panic(todo(""))
  1014  }
  1015  
  1016  // char *inet_ntoa(struct in_addr in);
  1017  func Xinet_ntoa(t *TLS, in1 in.In_addr) uintptr {
  1018  	panic(todo(""))
  1019  }
  1020  
  1021  func X__ccgo_in6addr_anyp(t *TLS) uintptr {
  1022  	return uintptr(unsafe.Pointer(&in6_addr_any))
  1023  }
  1024  
  1025  func Xabort(t *TLS) {
  1026  	if dmesgs {
  1027  		dmesg("%v:", origin(1))
  1028  	}
  1029  	p := Xcalloc(t, 1, types.Size_t(unsafe.Sizeof(signal.Sigaction{})))
  1030  	if p == 0 {
  1031  		panic("OOM")
  1032  	}
  1033  
  1034  	(*signal.Sigaction)(unsafe.Pointer(p)).F__sigaction_u.F__sa_handler = signal.SIG_DFL
  1035  	Xsigaction(t, signal.SIGABRT, p, 0)
  1036  	Xfree(t, p)
  1037  	unix.Kill(unix.Getpid(), syscall.Signal(signal.SIGABRT))
  1038  	panic(todo("unrechable"))
  1039  }
  1040  
  1041  // int fflush(FILE *stream);
  1042  func Xfflush(t *TLS, stream uintptr) int32 {
  1043  	return 0 //TODO
  1044  }
  1045  
  1046  // size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  1047  func Xfread(t *TLS, ptr uintptr, size, nmemb types.Size_t, stream uintptr) types.Size_t {
  1048  	m, _, err := unix.Syscall(unix.SYS_READ, uintptr(file(stream).fd()), ptr, uintptr(size*nmemb))
  1049  	if err != 0 {
  1050  		file(stream).setErr()
  1051  		return 0
  1052  	}
  1053  
  1054  	// if dmesgs {
  1055  	// 	// dmesg("%v: %d %#x x %#x: %#x\n%s", origin(1), file(stream).fd(), size, nmemb, types.Size_t(m)/size, hex.Dump(GoBytes(ptr, int(m))))
  1056  	// 	dmesg("%v: %d %#x x %#x: %#x", origin(1), file(stream).fd(), size, nmemb, types.Size_t(m)/size)
  1057  	// }
  1058  	return types.Size_t(m) / size
  1059  }
  1060  
  1061  // size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
  1062  func Xfwrite(t *TLS, ptr uintptr, size, nmemb types.Size_t, stream uintptr) types.Size_t {
  1063  	m, _, err := unix.Syscall(unix.SYS_WRITE, uintptr(file(stream).fd()), ptr, uintptr(size*nmemb))
  1064  	if err != 0 {
  1065  		file(stream).setErr()
  1066  		return 0
  1067  	}
  1068  
  1069  	// if dmesgs {
  1070  	// 	// dmesg("%v: %d %#x x %#x: %#x\n%s", origin(1), file(stream).fd(), size, nmemb, types.Size_t(m)/size, hex.Dump(GoBytes(ptr, int(m))))
  1071  	// 	dmesg("%v: %d %#x x %#x: %#x", origin(1), file(stream).fd(), size, nmemb, types.Size_t(m)/size)
  1072  	// }
  1073  	return types.Size_t(m) / size
  1074  }
  1075  
  1076  // int fclose(FILE *stream);
  1077  func Xfclose(t *TLS, stream uintptr) int32 {
  1078  	return file(stream).close(t)
  1079  }
  1080  
  1081  // int fputc(int c, FILE *stream);
  1082  func Xfputc(t *TLS, c int32, stream uintptr) int32 {
  1083  	if _, err := fwrite(file(stream).fd(), []byte{byte(c)}); err != nil {
  1084  		return stdio.EOF
  1085  	}
  1086  
  1087  	return int32(byte(c))
  1088  }
  1089  
  1090  // int fseek(FILE *stream, long offset, int whence);
  1091  func Xfseek(t *TLS, stream uintptr, offset long, whence int32) int32 {
  1092  	if n := Xlseek(t, int32(file(stream).fd()), types.Off_t(offset), whence); n < 0 {
  1093  		// if dmesgs {
  1094  		// 	dmesg("%v: fd %v, off %#x, whence %v: %v", origin(1), file(stream).fd(), offset, whenceStr(whence), n)
  1095  		// }
  1096  		file(stream).setErr()
  1097  		return -1
  1098  	}
  1099  
  1100  	// if dmesgs {
  1101  	// 	dmesg("%v: fd %v, off %#x, whence %v: ok", origin(1), file(stream).fd(), offset, whenceStr(whence))
  1102  	// }
  1103  	return 0
  1104  }
  1105  
  1106  // long ftell(FILE *stream);
  1107  func Xftell(t *TLS, stream uintptr) long {
  1108  	n := Xlseek(t, file(stream).fd(), 0, stdio.SEEK_CUR)
  1109  	if n < 0 {
  1110  		file(stream).setErr()
  1111  		return -1
  1112  	}
  1113  
  1114  	// if dmesgs {
  1115  	// 	dmesg("%v: fd %v, n %#x: ok %#x", origin(1), file(stream).fd(), n, long(n))
  1116  	// }
  1117  	return long(n)
  1118  }
  1119  
  1120  // int ferror(FILE *stream);
  1121  func Xferror(t *TLS, stream uintptr) int32 {
  1122  	return Bool32(file(stream).err())
  1123  }
  1124  
  1125  // int ungetc(int c, FILE *stream);
  1126  func Xungetc(t *TLS, c int32, stream uintptr) int32 {
  1127  	panic(todo(""))
  1128  }
  1129  
  1130  // int fscanf(FILE *stream, const char *format, ...);
  1131  func Xfscanf(t *TLS, stream, format, va uintptr) int32 {
  1132  	panic(todo(""))
  1133  }
  1134  
  1135  // int fputs(const char *s, FILE *stream);
  1136  func Xfputs(t *TLS, s, stream uintptr) int32 {
  1137  	if _, _, err := unix.Syscall(unix.SYS_WRITE, uintptr(file(stream).fd()), s, uintptr(Xstrlen(t, s))); err != 0 {
  1138  		return -1
  1139  	}
  1140  
  1141  	return 0
  1142  }
  1143  
  1144  var getservbynameStaticResult netdb.Servent
  1145  
  1146  // struct servent *getservbyname(const char *name, const char *proto);
  1147  func Xgetservbyname(t *TLS, name, proto uintptr) uintptr {
  1148  	var protoent *gonetdb.Protoent
  1149  	if proto != 0 {
  1150  		protoent = gonetdb.GetProtoByName(GoString(proto))
  1151  	}
  1152  	servent := gonetdb.GetServByName(GoString(name), protoent)
  1153  	if servent == nil {
  1154  		// if dmesgs {
  1155  		// 	dmesg("%q %q: nil (protoent %+v)", GoString(name), GoString(proto), protoent)
  1156  		// }
  1157  		return 0
  1158  	}
  1159  
  1160  	Xfree(t, (*netdb.Servent)(unsafe.Pointer(&getservbynameStaticResult)).Fs_name)
  1161  	if v := (*netdb.Servent)(unsafe.Pointer(&getservbynameStaticResult)).Fs_aliases; v != 0 {
  1162  		for {
  1163  			p := *(*uintptr)(unsafe.Pointer(v))
  1164  			if p == 0 {
  1165  				break
  1166  			}
  1167  
  1168  			Xfree(t, p)
  1169  			v += unsafe.Sizeof(uintptr(0))
  1170  		}
  1171  		Xfree(t, v)
  1172  	}
  1173  	Xfree(t, (*netdb.Servent)(unsafe.Pointer(&getservbynameStaticResult)).Fs_proto)
  1174  	cname, err := CString(servent.Name)
  1175  	if err != nil {
  1176  		getservbynameStaticResult = netdb.Servent{}
  1177  		return 0
  1178  	}
  1179  
  1180  	var protoname uintptr
  1181  	if protoent != nil {
  1182  		if protoname, err = CString(protoent.Name); err != nil {
  1183  			Xfree(t, cname)
  1184  			getservbynameStaticResult = netdb.Servent{}
  1185  			return 0
  1186  		}
  1187  	}
  1188  	var a []uintptr
  1189  	for _, v := range servent.Aliases {
  1190  		cs, err := CString(v)
  1191  		if err != nil {
  1192  			for _, v := range a {
  1193  				Xfree(t, v)
  1194  			}
  1195  			return 0
  1196  		}
  1197  
  1198  		a = append(a, cs)
  1199  	}
  1200  	v := Xcalloc(t, types.Size_t(len(a)+1), types.Size_t(unsafe.Sizeof(uintptr(0))))
  1201  	if v == 0 {
  1202  		Xfree(t, cname)
  1203  		Xfree(t, protoname)
  1204  		for _, v := range a {
  1205  			Xfree(t, v)
  1206  		}
  1207  		getservbynameStaticResult = netdb.Servent{}
  1208  		return 0
  1209  	}
  1210  	for _, p := range a {
  1211  		*(*uintptr)(unsafe.Pointer(v)) = p
  1212  		v += unsafe.Sizeof(uintptr(0))
  1213  	}
  1214  
  1215  	getservbynameStaticResult = netdb.Servent{
  1216  		Fs_name:    cname,
  1217  		Fs_aliases: v,
  1218  		Fs_port:    int32(servent.Port),
  1219  		Fs_proto:   protoname,
  1220  	}
  1221  	return uintptr(unsafe.Pointer(&getservbynameStaticResult))
  1222  }
  1223  
  1224  func Xreaddir64(t *TLS, dir uintptr) uintptr {
  1225  	return Xreaddir(t, dir)
  1226  }
  1227  
  1228  func __syscall(r, _ uintptr, errno syscall.Errno) long {
  1229  	if errno != 0 {
  1230  		return long(-errno)
  1231  	}
  1232  
  1233  	return long(r)
  1234  }
  1235  
  1236  func X__syscall1(t *TLS, trap, p1 long) long {
  1237  	return __syscall(unix.Syscall(uintptr(trap), uintptr(p1), 0, 0))
  1238  }
  1239  
  1240  func X__syscall3(t *TLS, trap, p1, p2, p3 long) long {
  1241  	return __syscall(unix.Syscall(uintptr(trap), uintptr(p1), uintptr(p2), uintptr(p3)))
  1242  }
  1243  
  1244  func X__syscall4(t *TLS, trap, p1, p2, p3, p4 long) long {
  1245  	return __syscall(unix.Syscall6(uintptr(trap), uintptr(p1), uintptr(p2), uintptr(p3), uintptr(p4), 0, 0))
  1246  }
  1247  
  1248  func fcntlCmdStr(cmd int32) string {
  1249  	switch cmd {
  1250  	case fcntl.F_GETOWN:
  1251  		return "F_GETOWN"
  1252  	case fcntl.F_SETLK:
  1253  		return "F_SETLK"
  1254  	case fcntl.F_GETLK:
  1255  		return "F_GETLK"
  1256  	case fcntl.F_SETFD:
  1257  		return "F_SETFD"
  1258  	case fcntl.F_GETFD:
  1259  		return "F_GETFD"
  1260  	default:
  1261  		return fmt.Sprintf("cmd(%d)", cmd)
  1262  	}
  1263  }
  1264  
  1265  // int setenv(const char *name, const char *value, int overwrite);
  1266  func Xsetenv(t *TLS, name, value uintptr, overwrite int32) int32 {
  1267  	panic(todo(""))
  1268  }
  1269  
  1270  // int unsetenv(const char *name);
  1271  func Xunsetenv(t *TLS, name uintptr) int32 {
  1272  	panic(todo(""))
  1273  }
  1274  
  1275  // int pause(void);
  1276  func Xpause(t *TLS) int32 {
  1277  	panic(todo(""))
  1278  }
  1279  
  1280  // ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
  1281  func Xwritev(t *TLS, fd int32, iov uintptr, iovcnt int32) types.Ssize_t {
  1282  	panic(todo(""))
  1283  }
  1284  
  1285  // int __isoc99_sscanf(const char *str, const char *format, ...);
  1286  func X__isoc99_sscanf(t *TLS, str, format, va uintptr) int32 {
  1287  	r := Xsscanf(t, str, format, va)
  1288  	// if dmesgs {
  1289  	// 	dmesg("%v: %q %q: %d", origin(1), GoString(str), GoString(format), r)
  1290  	// }
  1291  	return r
  1292  }
  1293  
  1294  // void __assert(const char * func, const char * file, int line, const char *expr) __dead2;
  1295  func X__assert(t *TLS, fn, file uintptr, line int32, expr uintptr) {
  1296  	X__assert_fail(t, expr, file, uint32(line), fn)
  1297  }
  1298  
  1299  // include/stdio.h:456:int	__swbuf(int, FILE *);
  1300  func X__swbuf(t *TLS, n int32, file uintptr) int32 {
  1301  	return Xfputc(t, n, file) //TODO improve performance, use a real buffer.
  1302  }
  1303  
  1304  // int rmdir(const char *pathname);
  1305  func Xrmdir(t *TLS, pathname uintptr) int32 {
  1306  	if err := unix.Rmdir(GoString(pathname)); err != nil {
  1307  		if dmesgs {
  1308  			dmesg("%v: %v FAIL", origin(1), err)
  1309  		}
  1310  		t.setErrno(err)
  1311  		return -1
  1312  	}
  1313  
  1314  	if dmesgs {
  1315  		dmesg("%v: ok", origin(1))
  1316  	}
  1317  	return 0
  1318  }
  1319  
  1320  // struct dirent *readdir(DIR *dirp);
  1321  func Xreaddir(t *TLS, dir uintptr) uintptr {
  1322  	if (*darwinDir)(unsafe.Pointer(dir)).eof {
  1323  		return 0
  1324  	}
  1325  
  1326  	if (*darwinDir)(unsafe.Pointer(dir)).l == (*darwinDir)(unsafe.Pointer(dir)).h {
  1327  		n, err := unix.Getdirentries((*darwinDir)(unsafe.Pointer(dir)).fd, (*darwinDir)(unsafe.Pointer(dir)).buf[:], nil)
  1328  		// trc("must read: %v %v", n, err)
  1329  		if n == 0 {
  1330  			if err != nil && err != io.EOF {
  1331  				if dmesgs {
  1332  					dmesg("%v: %v FAIL", origin(1), err)
  1333  				}
  1334  				t.setErrno(err)
  1335  			}
  1336  			(*darwinDir)(unsafe.Pointer(dir)).eof = true
  1337  			return 0
  1338  		}
  1339  
  1340  		(*darwinDir)(unsafe.Pointer(dir)).l = 0
  1341  		(*darwinDir)(unsafe.Pointer(dir)).h = n
  1342  		// trc("new l %v, h %v", (*darwinDir)(unsafe.Pointer(dir)).l, (*darwinDir)(unsafe.Pointer(dir)).h)
  1343  	}
  1344  	de := dir + unsafe.Offsetof(darwinDir{}.buf) + uintptr((*darwinDir)(unsafe.Pointer(dir)).l)
  1345  	(*darwinDir)(unsafe.Pointer(dir)).l += int((*unix.Dirent)(unsafe.Pointer(de)).Reclen)
  1346  	return de
  1347  }
  1348  
  1349  type darwinDir struct {
  1350  	buf [4096]byte
  1351  	fd  int
  1352  	h   int
  1353  	l   int
  1354  
  1355  	eof bool
  1356  }
  1357  
  1358  // int sscanf(const char *str, const char *format, ...);
  1359  func Xsscanf(t *TLS, str, format, va uintptr) int32 {
  1360  	r := scanf(strings.NewReader(GoString(str)), format, va)
  1361  	// if dmesgs {
  1362  	// 	dmesg("%v: %q %q: %d", origin(1), GoString(str), GoString(format), r)
  1363  	// }
  1364  	return r
  1365  }
  1366  
  1367  // int * __error(void);
  1368  func X__error(t *TLS) uintptr {
  1369  	return t.errnop
  1370  }
  1371  
  1372  func Xclosedir(t *TLS, dir uintptr) int32 {
  1373  	r := Xclose(t, int32((*darwinDir)(unsafe.Pointer(dir)).fd))
  1374  	Xfree(t, dir)
  1375  	return r
  1376  }
  1377  
  1378  // int __xuname(int namesize, void *namebuf)
  1379  func X__xuname(t *TLS, namesize int32, namebuf uintptr) int32 {
  1380  	return Xuname(t, namebuf)
  1381  }
  1382  
  1383  // int pipe(int pipefd[2]);
  1384  func Xpipe(t *TLS, pipefd uintptr) int32 {
  1385  	var a [2]int
  1386  	if err := syscall.Pipe(a[:]); err != nil {
  1387  		if dmesgs {
  1388  			dmesg("%v: %v FAIL", origin(1), err)
  1389  		}
  1390  		t.setErrno(err)
  1391  		return -1
  1392  	}
  1393  
  1394  	*(*[2]int32)(unsafe.Pointer(pipefd)) = [2]int32{int32(a[0]), int32(a[1])}
  1395  	if dmesgs {
  1396  		dmesg("%v: %v ok", origin(1), a)
  1397  	}
  1398  	return 0
  1399  }
  1400  
  1401  // char *inet_ntoa(struct in_addr in);
  1402  func X__inet_ntoa(t *TLS, in1 in.In_addr) uintptr {
  1403  	panic(todo(""))
  1404  }
  1405  
  1406  func Xmmap(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr {
  1407  	// Cannot avoid the syscall here, addr sometimes matter.
  1408  	data, _, err := unix.Syscall6(unix.SYS_MMAP, addr, uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
  1409  	if err != 0 {
  1410  		if dmesgs {
  1411  			dmesg("%v: %v FAIL", origin(1), err)
  1412  		}
  1413  		t.setErrno(err)
  1414  		return ^uintptr(0) // (void*)-1
  1415  	}
  1416  
  1417  	if dmesgs {
  1418  		dmesg("%v: %#x", origin(1), data)
  1419  	}
  1420  	return data
  1421  }
  1422  
  1423  const PTHREAD_MUTEX_DEFAULT = 0
  1424  
  1425  func X__ccgo_pthreadMutexattrGettype(tls *TLS, a uintptr) int32 { /* pthread_attr_get.c:93:5: */
  1426  	return (int32((*pthread_mutexattr_t)(unsafe.Pointer(a)).F__attr & uint32(3)))
  1427  }
  1428  
  1429  func X__ccgo_getMutexType(tls *TLS, m uintptr) int32 { /* pthread_mutex_lock.c:3:5: */
  1430  	return (*(*int32)(unsafe.Pointer((m /* &.__u */ /* &.__i */))) & 15)
  1431  }
  1432  
  1433  func X__ccgo_pthreadAttrGetDetachState(tls *TLS, a uintptr) int32 { /* pthread_attr_get.c:3:5: */
  1434  	return *(*int32)(unsafe.Pointer((a /* &.__u */ /* &.__i */) + 6*4))
  1435  }
  1436  
  1437  func Xpthread_attr_init(t *TLS, pAttr uintptr) int32 {
  1438  	*(*pthread.Pthread_attr_t)(unsafe.Pointer(pAttr)) = pthread.Pthread_attr_t(0)
  1439  	return 0
  1440  }
  1441  
  1442  // The pthread_mutex_init() function shall initialize the mutex referenced by
  1443  // mutex with attributes specified by attr. If attr is NULL, the default mutex
  1444  // attributes are used; the effect shall be the same as passing the address of
  1445  // a default mutex attributes object. Upon successful initialization, the state
  1446  // of the mutex becomes initialized and unlocked.
  1447  //
  1448  // If successful, the pthread_mutex_destroy() and pthread_mutex_init()
  1449  // functions shall return zero; otherwise, an error number shall be returned to
  1450  // indicate the error.
  1451  //
  1452  // int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
  1453  func Xpthread_mutex_init(t *TLS, pMutex, pAttr uintptr) int32 {
  1454  	typ := PTHREAD_MUTEX_DEFAULT
  1455  	if pAttr != 0 {
  1456  		typ = int(X__ccgo_pthreadMutexattrGettype(t, pAttr))
  1457  	}
  1458  	mutexesMu.Lock()
  1459  
  1460  	defer mutexesMu.Unlock()
  1461  
  1462  	mutexes[pMutex] = newMutex(typ)
  1463  	return 0
  1464  }
  1465  
  1466  func Xpthread_attr_getdetachstate(tls *TLS, a uintptr, state uintptr) int32 { /* pthread_attr_get.c:7:5: */
  1467  	*(*int32)(unsafe.Pointer(state)) = *(*int32)(unsafe.Pointer((a /* &.__u */ /* &.__i */) + 6*4))
  1468  	return 0
  1469  }
  1470  
  1471  func Xpthread_attr_setdetachstate(tls *TLS, a uintptr, state int32) int32 { /* pthread_attr_setdetachstate.c:3:5: */
  1472  	if uint32(state) > 1 {
  1473  		return 22
  1474  	}
  1475  	*(*int32)(unsafe.Pointer((a /* &.__u */ /* &.__i */) + 6*4)) = state
  1476  	return 0
  1477  }
  1478  
  1479  func Xpthread_mutexattr_destroy(tls *TLS, a uintptr) int32 { /* pthread_mutexattr_destroy.c:3:5: */
  1480  	return 0
  1481  }
  1482  
  1483  func Xpthread_mutexattr_init(tls *TLS, a uintptr) int32 { /* pthread_mutexattr_init.c:3:5: */
  1484  	*(*pthread_mutexattr_t)(unsafe.Pointer(a)) = pthread_mutexattr_t{}
  1485  	return 0
  1486  }
  1487  
  1488  func Xpthread_mutexattr_settype(tls *TLS, a uintptr, type1 int32) int32 { /* pthread_mutexattr_settype.c:3:5: */
  1489  	if uint32(type1) > uint32(2) {
  1490  		return 22
  1491  	}
  1492  	(*pthread_mutexattr_t)(unsafe.Pointer(a)).F__attr = (((*pthread_mutexattr_t)(unsafe.Pointer(a)).F__attr & Uint32FromInt32(CplInt32(3))) | uint32(type1))
  1493  	return 0
  1494  }
  1495  
  1496  // int uuid_parse( char *in, uuid_t uu);
  1497  func Xuuid_parse(t *TLS, in uintptr, uu uintptr) int32 {
  1498  	r, err := guuid.Parse(GoString(in))
  1499  	if err != nil {
  1500  		return -1
  1501  	}
  1502  
  1503  	copy((*RawMem)(unsafe.Pointer(uu))[:unsafe.Sizeof(uuid.Uuid_t{})], r[:])
  1504  	return 0
  1505  }
  1506  
  1507  func X__srget(t *TLS, stream uintptr) int32 { return Xgetc(t, stream) }
  1508  
  1509  func X___tolower(t *TLS, r rune) rune {
  1510  	return unicode.ToLower(r)
  1511  }
  1512  
  1513  func X___toupper(t *TLS, r rune) rune {
  1514  	return unicode.ToLower(r)
  1515  }
  1516  
  1517  // uint16_t __builtin_bswap16 (uint32_t x)
  1518  func Xbswap16(t *TLS, x uint16) uint16 {
  1519  	return X__builtin_bswap16(t, x)
  1520  }
  1521  
  1522  // uint32_t __builtin_bswap32 (uint32_t x)
  1523  func Xbswap32(t *TLS, x uint32) uint32 {
  1524  	return X__builtin_bswap32(t, x)
  1525  }
  1526  
  1527  // uint64_t __builtin_bswap64 (uint64_t x)
  1528  func Xbswap64(t *TLS, x uint64) uint64 {
  1529  	return X__builtin_bswap64(t, x)
  1530  }