gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

libc_linux.go (41678B)


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