libc_freebsd.go (39276B)
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 "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 guuid "github.com/google/uuid" 22 "golang.org/x/sys/unix" 23 "modernc.org/libc/errno" 24 "modernc.org/libc/fcntl" 25 "modernc.org/libc/fts" 26 gonetdb "modernc.org/libc/honnef.co/go/netdb" 27 "modernc.org/libc/langinfo" 28 "modernc.org/libc/limits" 29 "modernc.org/libc/netdb" 30 "modernc.org/libc/netinet/in" 31 "modernc.org/libc/pthread" 32 "modernc.org/libc/signal" 33 "modernc.org/libc/stdio" 34 "modernc.org/libc/sys/socket" 35 "modernc.org/libc/sys/stat" 36 "modernc.org/libc/sys/types" 37 "modernc.org/libc/termios" 38 "modernc.org/libc/time" 39 "modernc.org/libc/unistd" 40 "modernc.org/libc/uuid" 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 }