package libc
import (
"bufio"
"encoding/hex"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"syscall"
gotime "time"
"unsafe"
"golang.org/x/sys/unix"
"modernc.org/libc/errno"
"modernc.org/libc/fcntl"
"modernc.org/libc/fts"
gonetdb "modernc.org/libc/honnef.co/go/netdb"
"modernc.org/libc/langinfo"
"modernc.org/libc/limits"
"modernc.org/libc/netdb"
"modernc.org/libc/netinet/in"
"modernc.org/libc/pwd"
"modernc.org/libc/signal"
"modernc.org/libc/stdio"
"modernc.org/libc/sys/socket"
"modernc.org/libc/sys/stat"
"modernc.org/libc/sys/types"
"modernc.org/libc/termios"
"modernc.org/libc/time"
"modernc.org/libc/unistd"
)
const (
maxPathLen = 1024
)
type (
long = types .User_long_t
ulong = types .User_ulong_t
)
var X__stderrp = Xstdout
var X__stdinp = Xstdin
var X__stdoutp = Xstdout
type file uintptr
func (f file ) fd () int32 { return int32 ((*stdio .FILE )(unsafe .Pointer (f )).F_file ) }
func (f file ) setFd (fd int32 ) { (*stdio .FILE )(unsafe .Pointer (f )).F_file = int16 (fd ) }
func (f file ) err () bool {
return (*stdio .FILE )(unsafe .Pointer (f )).F_flags &1 != 0
}
func (f file ) setErr () {
(*stdio .FILE )(unsafe .Pointer (f )).F_flags |= 1
}
func (f file ) close (t *TLS ) int32 {
r := Xclose (t , f .fd ())
Xfree (t , uintptr (f ))
if r < 0 {
return stdio .EOF
}
return 0
}
func newFile (t *TLS , fd int32 ) uintptr {
p := Xcalloc (t , 1 , types .Size_t (unsafe .Sizeof (stdio .FILE {})))
if p == 0 {
return 0
}
file (p ).setFd (fd )
return p
}
func fwrite (fd int32 , b []byte ) (int , error ) {
if fd == unistd .STDOUT_FILENO {
return write (b )
}
if dmesgs {
dmesg ("%v: fd %v: %s" , origin (1 ), fd , hex .Dump (b ))
}
return unix .Write (int (fd ), b )
}
func X__inline_isnand (t *TLS , x float64 ) int32 { return Xisnan (t , x ) }
func X__inline_isnanf (t *TLS , x float32 ) int32 { return Xisnanf (t , x ) }
func X__inline_isnanl (t *TLS , x float64 ) int32 { return Xisnan (t , x ) }
func Xfprintf (t *TLS , stream , format , args uintptr ) int32 {
n , _ := fwrite (int32 ((*stdio .FILE )(unsafe .Pointer (stream )).F_file ), printf (format , args ))
return int32 (n )
}
func Xusleep (t *TLS , usec types .Useconds_t ) int32 {
gotime .Sleep (gotime .Microsecond * gotime .Duration (usec ))
return 0
}
func Xfutimes (t *TLS , fd int32 , tv uintptr ) int32 {
var a []unix .Timeval
if tv != 0 {
a = make ([]unix .Timeval , 2 )
a [0 ] = *(*unix .Timeval )(unsafe .Pointer (tv ))
a [1 ] = *(*unix .Timeval )(unsafe .Pointer (tv + unsafe .Sizeof (unix .Timeval {})))
}
if err := unix .Futimes (int (fd ), a ); err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return 0
}
func Xsrandomdev (t *TLS ) {
panic (todo ("" ))
}
func Xgethostuuid (t *TLS , id uintptr , wait uintptr ) int32 {
if _ , _ , err := unix .Syscall (unix .SYS_GETHOSTUUID , id , wait , 0 ); err != 0 {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return 0
}
func Xflock (t *TLS , fd , operation int32 ) int32 {
if err := unix .Flock (int (fd ), int (operation )); err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return 0
}
func Xfsctl (t *TLS , path uintptr , request ulong , data uintptr , options uint32 ) int32 {
panic (todo ("" ))
}
func X__error (t *TLS ) uintptr {
return t .errnop
}
func Xisspace (t *TLS , c int32 ) int32 {
return __isspace (t , c )
}
func X__assert_rtn (t *TLS , function , file uintptr , line int32 , assertion uintptr ) {
panic (todo ("" ))
}
func Xgetrusage (t *TLS , who int32 , usage uintptr ) int32 {
panic (todo ("" ))
}
func Xfgets (t *TLS , s uintptr , size int32 , stream uintptr ) uintptr {
fd := int ((*stdio .FILE )(unsafe .Pointer (stream )).F_file )
var b []byte
buf := [1 ]byte {}
for ; size > 0 ; size -- {
n , err := unix .Read (fd , buf [:])
if n != 0 {
b = append (b , buf [0 ])
if buf [0 ] == '\n' {
b = append (b , 0 )
copy ((*RawMem )(unsafe .Pointer (s ))[:len (b ):len (b )], b )
return s
}
continue
}
switch {
case n == 0 && err == nil && len (b ) == 0 :
return 0
default :
panic (todo ("" ))
}
}
panic (todo ("" ))
}
func Xlstat (t *TLS , pathname , statbuf uintptr ) int32 {
return Xlstat64 (t , pathname , statbuf )
}
func Xstat (t *TLS , pathname , statbuf uintptr ) int32 {
return Xstat64 (t , pathname , statbuf )
}
func Xchdir (t *TLS , path uintptr ) int32 {
if err := unix .Chdir (GoString (path )); err != nil {
if dmesgs {
dmesg ("%v: %q: %v FAIL" , origin (1 ), GoString (path ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: %q: ok" , origin (1 ), GoString (path ))
}
return 0
}
var localtime time .Tm
func Xlocaltime (_ *TLS , timep uintptr ) uintptr {
loc := gotime .Local
if r := getenv (Environ (), "TZ" ); r != 0 {
zone , off := parseZone (GoString (r ))
loc = gotime .FixedZone (zone , -off )
}
ut := *(*time .Time_t )(unsafe .Pointer (timep ))
t := gotime .Unix (int64 (ut ), 0 ).In (loc )
localtime .Ftm_sec = int32 (t .Second ())
localtime .Ftm_min = int32 (t .Minute ())
localtime .Ftm_hour = int32 (t .Hour ())
localtime .Ftm_mday = int32 (t .Day ())
localtime .Ftm_mon = int32 (t .Month () - 1 )
localtime .Ftm_year = int32 (t .Year () - 1900 )
localtime .Ftm_wday = int32 (t .Weekday ())
localtime .Ftm_yday = int32 (t .YearDay ())
localtime .Ftm_isdst = Bool32 (isTimeDST (t ))
return uintptr (unsafe .Pointer (&localtime ))
}
func Xlocaltime_r (_ *TLS , timep , result uintptr ) uintptr {
panic (todo ("" ))
}
func Xopen (t *TLS , pathname uintptr , flags int32 , args uintptr ) int32 {
var mode types .Mode_t
if args != 0 {
mode = *(*types .Mode_t )(unsafe .Pointer (args ))
}
fd , err := unix .Open (GoString (pathname ), int (flags ), uint32 (mode ))
if err != nil {
if dmesgs {
dmesg ("%v: %q %#x %#o: %v FAIL" , origin (1 ), GoString (pathname ), flags , mode , err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: %q flags %#x mode %#o: fd %v" , origin (1 ), GoString (pathname ), flags , mode , fd )
}
return int32 (fd )
}
func Xlseek (t *TLS , fd int32 , offset types .Off_t , whence int32 ) types .Off_t {
return types .Off_t (Xlseek64 (t , fd , offset , whence ))
}
func whenceStr (whence int32 ) string {
switch whence {
case fcntl .SEEK_CUR :
return "SEEK_CUR"
case fcntl .SEEK_END :
return "SEEK_END"
case fcntl .SEEK_SET :
return "SEEK_SET"
default :
return fmt .Sprintf ("whence(%d)" , whence )
}
}
var fsyncStatbuf stat .Stat
func Xfsync (t *TLS , fd int32 ) int32 {
if noFsync {
return Xfstat (t , fd , uintptr (unsafe .Pointer (&fsyncStatbuf )))
}
if err := unix .Fsync (int (fd )); err != nil {
if dmesgs {
dmesg ("%v: %v: %v FAIL" , origin (1 ), fd , err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: %d: ok" , origin (1 ), fd )
}
return 0
}
func Xsysconf (t *TLS , name int32 ) long {
switch name {
case unistd .X_SC_PAGESIZE :
return long (unix .Getpagesize ())
}
panic (todo ("" ))
}
func Xclose (t *TLS , fd int32 ) int32 {
if err := unix .Close (int (fd )); err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: %d: ok" , origin (1 ), fd )
}
return 0
}
func Xgetcwd (t *TLS , buf uintptr , size types .Size_t ) uintptr {
if _ , err := unix .Getcwd ((*RawMem )(unsafe .Pointer (buf ))[:size :size ]); err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return 0
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return buf
}
func Xfstat (t *TLS , fd int32 , statbuf uintptr ) int32 {
return Xfstat64 (t , fd , statbuf )
}
func Xftruncate (t *TLS , fd int32 , length types .Off_t ) int32 {
if err := unix .Ftruncate (int (fd ), int64 (length )); err != nil {
if dmesgs {
dmesg ("%v: fd %d: %v FAIL" , origin (1 ), fd , err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: %d %#x: ok" , origin (1 ), fd , length )
}
return 0
}
func Xfcntl (t *TLS , fd , cmd int32 , args uintptr ) int32 {
return Xfcntl64 (t , fd , cmd , args )
}
func Xread (t *TLS , fd int32 , buf uintptr , count types .Size_t ) types .Ssize_t {
var n int
var err error
switch {
case count == 0 :
n , err = unix .Read (int (fd ), nil )
default :
n , err = unix .Read (int (fd ), (*RawMem )(unsafe .Pointer (buf ))[:count :count ])
if dmesgs && err == nil {
dmesg ("%v: fd %v, count %#x, n %#x\n%s" , origin (1 ), fd , count , n , hex .Dump ((*RawMem )(unsafe .Pointer (buf ))[:n :n ]))
}
}
if err != nil {
if dmesgs {
dmesg ("%v: fd %v, %v FAIL" , origin (1 ), fd , err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return types .Ssize_t (n )
}
func Xwrite (t *TLS , fd int32 , buf uintptr , count types .Size_t ) types .Ssize_t {
var n int
var err error
switch {
case count == 0 :
n , err = unix .Write (int (fd ), nil )
default :
n , err = unix .Write (int (fd ), (*RawMem )(unsafe .Pointer (buf ))[:count :count ])
if dmesgs {
dmesg ("%v: fd %v, count %#x\n%s" , origin (1 ), fd , count , hex .Dump ((*RawMem )(unsafe .Pointer (buf ))[:count :count ]))
}
}
if err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return types .Ssize_t (n )
}
func Xfchmod (t *TLS , fd int32 , mode types .Mode_t ) int32 {
if err := unix .Fchmod (int (fd ), uint32 (mode )); err != nil {
if dmesgs {
dmesg ("%v: %d %#o: %v FAIL" , origin (1 ), fd , mode , err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: %d %#o: ok" , origin (1 ), fd , mode )
}
return 0
}
func Xfchown (t *TLS , fd int32 , owner types .Uid_t , group types .Gid_t ) int32 {
panic (todo ("" ))
}
func Xgeteuid (t *TLS ) types .Uid_t {
r := types .Uid_t (unix .Geteuid ())
if dmesgs {
dmesg ("%v: %v" , origin (1 ), r )
}
return r
}
func Xmmap (t *TLS , addr uintptr , length types .Size_t , prot , flags , fd int32 , offset types .Off_t ) uintptr {
data , _ , err := unix .Syscall6 (unix .SYS_MMAP , addr , uintptr (length ), uintptr (prot ), uintptr (flags ), uintptr (fd ), uintptr (offset ))
if err != 0 {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return ^uintptr (0 )
}
if dmesgs {
dmesg ("%v: %#x" , origin (1 ), data )
}
return data
}
func Xmunmap (t *TLS , addr uintptr , length types .Size_t ) int32 {
if _ , _ , err := unix .Syscall (unix .SYS_MUNMAP , addr , uintptr (length ), 0 ); err != 0 {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
return 0
}
func Xgettimeofday (t *TLS , tv , tz uintptr ) int32 {
if tz != 0 {
panic (todo ("" ))
}
var tvs unix .Timeval
err := unix .Gettimeofday (&tvs )
if err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
*(*unix .Timeval )(unsafe .Pointer (tv )) = tvs
return 0
}
func Xgetsockopt (t *TLS , sockfd , level , optname int32 , optval , optlen uintptr ) int32 {
panic (todo ("" ))
}
func Xsetsockopt (t *TLS , sockfd , level , optname int32 , optval uintptr , optlen socket .Socklen_t ) int32 {
panic (todo ("" ))
}
func Xioctl (t *TLS , fd int32 , request ulong , va uintptr ) int32 {
panic (todo ("" ))
}
func Xgetsockname (t *TLS , sockfd int32 , addr , addrlen uintptr ) int32 {
if _ , _ , err := unix .Syscall (unix .SYS_GETSOCKNAME , uintptr (sockfd ), addr , addrlen ); err != 0 {
if dmesgs {
dmesg ("%v: fd %v: %v FAIL" , origin (1 ), sockfd , err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: fd %v: ok" , origin (1 ), sockfd )
}
return 0
}
func Xselect (t *TLS , nfds int32 , readfds , writefds , exceptfds , timeout uintptr ) int32 {
n , err := unix .Select (
int (nfds ),
(*unix .FdSet )(unsafe .Pointer (readfds )),
(*unix .FdSet )(unsafe .Pointer (writefds )),
(*unix .FdSet )(unsafe .Pointer (exceptfds )),
(*unix .Timeval )(unsafe .Pointer (timeout )),
)
if err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return int32 (n )
}
func Xmkfifo (t *TLS , pathname uintptr , mode types .Mode_t ) int32 {
panic (todo ("" ))
}
func Xumask (t *TLS , mask types .Mode_t ) types .Mode_t {
return types .Mode_t (unix .Umask (int (mask )))
}
func Xwaitpid (t *TLS , pid types .Pid_t , wstatus uintptr , optname int32 ) types .Pid_t {
n , err := unix .Wait4 (int (pid ), (*unix .WaitStatus )(unsafe .Pointer (wstatus )), int (optname ), nil )
if err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return types .Pid_t (n )
}
func Xuname (t *TLS , buf uintptr ) int32 {
if err := unix .Uname ((*unix .Utsname )(unsafe .Pointer (buf ))); err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return 0
}
func Xrecv (t *TLS , sockfd int32 , buf uintptr , len types .Size_t , flags int32 ) types .Ssize_t {
panic (todo ("" ))
}
func Xsend (t *TLS , sockfd int32 , buf uintptr , len types .Size_t , flags int32 ) types .Ssize_t {
panic (todo ("" ))
}
func Xshutdown (t *TLS , sockfd , how int32 ) int32 {
panic (todo ("" ))
}
func Xgetpeername (t *TLS , sockfd int32 , addr uintptr , addrlen uintptr ) int32 {
panic (todo ("" ))
}
func Xsocket (t *TLS , domain , type1 , protocol int32 ) int32 {
panic (todo ("" ))
}
func Xbind (t *TLS , sockfd int32 , addr uintptr , addrlen uint32 ) int32 {
panic (todo ("" ))
}
func Xconnect (t *TLS , sockfd int32 , addr uintptr , addrlen uint32 ) int32 {
panic (todo ("" ))
}
func Xlisten (t *TLS , sockfd , backlog int32 ) int32 {
panic (todo ("" ))
}
func Xaccept (t *TLS , sockfd int32 , addr uintptr , addrlen uintptr ) int32 {
panic (todo ("" ))
}
func Xgetuid (t *TLS ) types .Uid_t {
r := types .Uid_t (os .Getuid ())
if dmesgs {
dmesg ("%v: %v" , origin (1 ), r )
}
return r
}
func Xgetpid (t *TLS ) int32 {
r := int32 (os .Getpid ())
if dmesgs {
dmesg ("%v: %v" , origin (1 ), r )
}
return r
}
func Xsystem (t *TLS , command uintptr ) int32 {
s := GoString (command )
if command == 0 {
panic (todo ("" ))
}
cmd := exec .Command ("sh" , "-c" , s )
cmd .Stdout = os .Stdout
cmd .Stderr = os .Stderr
err := cmd .Run ()
if err != nil {
ps := err .(*exec .ExitError )
return int32 (ps .ExitCode ())
}
return 0
}
var staticGetpwuid pwd .Passwd
func init () {
atExit = append (atExit , func () { closePasswd (&staticGetpwuid ) })
}
func closePasswd (p *pwd .Passwd ) {
Xfree (nil , p .Fpw_name )
Xfree (nil , p .Fpw_passwd )
Xfree (nil , p .Fpw_gecos )
Xfree (nil , p .Fpw_dir )
Xfree (nil , p .Fpw_shell )
*p = pwd .Passwd {}
}
func Xgetpwuid (t *TLS , uid uint32 ) uintptr {
f , err := os .Open ("/etc/passwd" )
if err != nil {
if dmesgs {
dmesg ("%v: %v" , origin (1 ), err )
}
panic (todo ("" , err ))
}
defer f .Close ()
sid := strconv .Itoa (int (uid ))
sc := bufio .NewScanner (f )
for sc .Scan () {
s := strings .TrimSpace (sc .Text ())
if len (s ) == 0 || strings .HasPrefix (s , "#" ) {
continue
}
a := strings .Split (sc .Text (), ":" )
if len (a ) < 7 {
panic (todo ("%q" , sc .Text ()))
}
if a [2 ] == sid {
uid , err := strconv .Atoi (a [2 ])
if err != nil {
panic (todo ("" ))
}
gid , err := strconv .Atoi (a [3 ])
if err != nil {
panic (todo ("" ))
}
closePasswd (&staticGetpwuid )
gecos := a [4 ]
if strings .Contains (gecos , "," ) {
a := strings .Split (gecos , "," )
gecos = a [0 ]
}
initPasswd (t , &staticGetpwuid , a [0 ], a [1 ], uint32 (uid ), uint32 (gid ), gecos , a [5 ], a [6 ])
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return uintptr (unsafe .Pointer (&staticGetpwuid ))
}
}
if sc .Err () != nil {
panic (todo ("" ))
}
if dmesgs {
dmesg ("%v: 0" , origin (1 ))
}
return 0
}
func initPasswd (t *TLS , p *pwd .Passwd , name , pwd string , uid , gid uint32 , gecos , dir , shell string ) {
p .Fpw_name = cString (t , name )
p .Fpw_passwd = cString (t , pwd )
p .Fpw_uid = uid
p .Fpw_gid = gid
p .Fpw_gecos = cString (t , gecos )
p .Fpw_dir = cString (t , dir )
p .Fpw_shell = cString (t , shell )
}
func Xsetvbuf (t *TLS , stream , buf uintptr , mode int32 , size types .Size_t ) int32 {
return 0
}
func Xraise (t *TLS , sig int32 ) int32 {
panic (todo ("" ))
}
func Xfileno (t *TLS , stream uintptr ) int32 {
if stream == 0 {
if dmesgs {
dmesg ("%v: FAIL" , origin (1 ))
}
t .setErrno (errno .EBADF )
return -1
}
if fd := int32 ((*stdio .FILE )(unsafe .Pointer (stream )).F_file ); fd >= 0 {
return fd
}
if dmesgs {
dmesg ("%v: FAIL" , origin (1 ))
}
t .setErrno (errno .EBADF )
return -1
}
func Xgetpwnam (t *TLS , name uintptr ) uintptr {
panic (todo ("" ))
}
func Xgetgrnam (t *TLS , name uintptr ) uintptr {
panic (todo ("" ))
}
func Xgetgrgid (t *TLS , gid uint32 ) uintptr {
panic (todo ("" ))
}
func Xmkstemps (t *TLS , template uintptr , suffixlen int32 ) int32 {
panic (todo ("" ))
}
func Xmkstemps64 (t *TLS , template uintptr , suffixlen int32 ) int32 {
len := uintptr (Xstrlen (t , template ))
x := template + uintptr (len -6 ) - uintptr (suffixlen )
for i := uintptr (0 ); i < 6 ; i ++ {
if *(*byte )(unsafe .Pointer (x + i )) != 'X' {
if dmesgs {
dmesg ("%v: FAIL" , origin (1 ))
}
t .setErrno (errno .EINVAL )
return -1
}
}
fd , err := tempFile (template , x )
if err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
return int32 (fd )
}
func Xmkstemp (t *TLS , template uintptr ) int32 {
return Xmkstemps64 (t , template , 0 )
}
func newFtsent (t *TLS , info int , path string , stat *unix .Stat_t , err syscall .Errno ) (r *fts .FTSENT ) {
var statp uintptr
if stat != nil {
statp = Xmalloc (t , types .Size_t (unsafe .Sizeof (unix .Stat_t {})))
if statp == 0 {
panic ("OOM" )
}
*(*unix .Stat_t )(unsafe .Pointer (statp )) = *stat
}
csp , errx := CString (path )
if errx != nil {
panic ("OOM" )
}
return &fts .FTSENT {
Ffts_info : uint16 (info ),
Ffts_path : csp ,
Ffts_pathlen : uint16 (len (path )),
Ffts_statp : statp ,
Ffts_errno : int32 (err ),
}
}
func newCFtsent (t *TLS , info int , path string , stat *unix .Stat_t , err syscall .Errno ) uintptr {
p := Xcalloc (t , 1 , types .Size_t (unsafe .Sizeof (fts .FTSENT {})))
if p == 0 {
panic ("OOM" )
}
*(*fts .FTSENT )(unsafe .Pointer (p )) = *newFtsent (t , info , path , stat , err )
return p
}
func ftsentClose (t *TLS , p uintptr ) {
Xfree (t , (*fts .FTSENT )(unsafe .Pointer (p )).Ffts_path )
Xfree (t , (*fts .FTSENT )(unsafe .Pointer (p )).Ffts_statp )
}
type ftstream struct {
s []uintptr
x int
}
func (f *ftstream ) close (t *TLS ) {
for _ , p := range f .s {
ftsentClose (t , p )
Xfree (t , p )
}
*f = ftstream {}
}
func Xfts_open (t *TLS , path_argv uintptr , options int32 , compar uintptr ) uintptr {
f := &ftstream {}
var walk func (string )
walk = func (path string ) {
var fi os .FileInfo
var err error
switch {
case options &fts .FTS_LOGICAL != 0 :
fi , err = os .Stat (path )
case options &fts .FTS_PHYSICAL != 0 :
fi , err = os .Lstat (path )
default :
panic (todo ("" ))
}
if err != nil {
return
}
var statp *unix .Stat_t
if options &fts .FTS_NOSTAT == 0 {
var stat unix .Stat_t
switch {
case options &fts .FTS_LOGICAL != 0 :
if err := unix .Stat (path , &stat ); err != nil {
panic (todo ("" ))
}
case options &fts .FTS_PHYSICAL != 0 :
if err := unix .Lstat (path , &stat ); err != nil {
panic (todo ("" ))
}
default :
panic (todo ("" ))
}
statp = &stat
}
out :
switch {
case fi .IsDir ():
f .s = append (f .s , newCFtsent (t , fts .FTS_D , path , statp , 0 ))
g , err := os .Open (path )
switch x := err .(type ) {
case nil :
case *os .PathError :
f .s = append (f .s , newCFtsent (t , fts .FTS_DNR , path , statp , errno .EACCES ))
break out
default :
panic (todo ("%q: %v %T" , path , x , x ))
}
names , err := g .Readdirnames (-1 )
g .Close ()
if err != nil {
panic (todo ("" ))
}
for _ , name := range names {
walk (path + "/" + name )
if f == nil {
break out
}
}
f .s = append (f .s , newCFtsent (t , fts .FTS_DP , path , statp , 0 ))
default :
info := fts .FTS_F
if fi .Mode ()&os .ModeSymlink != 0 {
info = fts .FTS_SL
}
switch {
case statp != nil :
f .s = append (f .s , newCFtsent (t , info , path , statp , 0 ))
case options &fts .FTS_NOSTAT != 0 :
f .s = append (f .s , newCFtsent (t , fts .FTS_NSOK , path , nil , 0 ))
default :
panic (todo ("" ))
}
}
}
for {
p := *(*uintptr )(unsafe .Pointer (path_argv ))
if p == 0 {
if f == nil {
return 0
}
if compar != 0 {
panic (todo ("" ))
}
return addObject (f )
}
walk (GoString (p ))
path_argv += unsafe .Sizeof (uintptr (0 ))
}
}
func Xfts_read (t *TLS , ftsp uintptr ) uintptr {
f := getObject (ftsp ).(*ftstream )
if f .x == len (f .s ) {
if dmesgs {
dmesg ("%v: FAIL" , origin (1 ))
}
t .setErrno (0 )
return 0
}
r := f .s [f .x ]
if e := (*fts .FTSENT )(unsafe .Pointer (r )).Ffts_errno ; e != 0 {
if dmesgs {
dmesg ("%v: FAIL" , origin (1 ))
}
t .setErrno (e )
}
f .x ++
return r
}
func Xfts_close (t *TLS , ftsp uintptr ) int32 {
getObject (ftsp ).(*ftstream ).close (t )
removeObject (ftsp )
return 0
}
func Xtzset (t *TLS ) {
}
func Xstrerror (t *TLS , errnum int32 ) uintptr {
panic (todo ("" ))
}
func Xdlopen (t *TLS , filename uintptr , flags int32 ) uintptr {
panic (todo ("" ))
}
func Xdlerror (t *TLS ) uintptr {
panic (todo ("" ))
}
func Xdlclose (t *TLS , handle uintptr ) int32 {
panic (todo ("" ))
}
func Xdlsym (t *TLS , handle , symbol uintptr ) uintptr {
panic (todo ("" ))
}
func Xperror (t *TLS , s uintptr ) {
panic (todo ("" ))
}
func Xpclose (t *TLS , stream uintptr ) int32 {
panic (todo ("" ))
}
func Xgai_strerror (t *TLS , errcode int32 ) uintptr {
panic (todo ("" ))
}
func Xtcgetattr (t *TLS , fd int32 , termios_p uintptr ) int32 {
panic (todo ("" ))
}
func Xtcsetattr (t *TLS , fd , optional_actions int32 , termios_p uintptr ) int32 {
panic (todo ("" ))
}
func Xcfgetospeed (t *TLS , termios_p uintptr ) termios .Speed_t {
panic (todo ("" ))
}
func Xcfsetospeed (...interface {}) int32 {
panic (todo ("" ))
}
func Xcfsetispeed (...interface {}) int32 {
panic (todo ("" ))
}
func Xfork (t *TLS ) int32 {
if dmesgs {
dmesg ("%v: FAIL" , origin (1 ))
}
t .setErrno (errno .ENOSYS )
return -1
}
func Xsetlocale (t *TLS , category int32 , locale uintptr ) uintptr {
return 0
}
func Xnl_langinfo (t *TLS , item langinfo .Nl_item ) uintptr {
panic (todo ("" ))
}
func Xpopen (t *TLS , command , type1 uintptr ) uintptr {
panic (todo ("" ))
}
func Xrealpath (t *TLS , path , resolved_path uintptr ) uintptr {
s , err := filepath .EvalSymlinks (GoString (path ))
if err != nil {
if os .IsNotExist (err ) {
if dmesgs {
dmesg ("%v: %q: %v FAIL" , origin (1 ), GoString (path ), err )
}
t .setErrno (errno .ENOENT )
return 0
}
panic (todo ("" , err ))
}
if resolved_path == 0 {
panic (todo ("" ))
}
if len (s ) >= limits .PATH_MAX {
s = s [:limits .PATH_MAX -1 ]
}
copy ((*RawMem )(unsafe .Pointer (resolved_path ))[:len (s ):len (s )], s )
(*RawMem )(unsafe .Pointer (resolved_path ))[len (s )] = 0
if dmesgs {
dmesg ("%v: %q: ok" , origin (1 ), GoString (path ))
}
return resolved_path
}
func Xgmtime_r (t *TLS , timep , result uintptr ) uintptr {
panic (todo ("" ))
}
func Xinet_ntoa (t *TLS , in1 in .In_addr ) uintptr {
panic (todo ("" ))
}
func X__ccgo_in6addr_anyp (t *TLS ) uintptr {
panic (todo ("" ))
}
func Xabort (t *TLS ) {
if dmesgs {
dmesg ("%v:" , origin (1 ))
}
p := Xcalloc (t , 1 , types .Size_t (unsafe .Sizeof (signal .Sigaction {})))
if p == 0 {
panic ("OOM" )
}
(*signal .Sigaction )(unsafe .Pointer (p )).F__sigaction_u .F__sa_handler = signal .SIG_DFL
Xsigaction (t , signal .SIGABRT , p , 0 )
Xfree (t , p )
unix .Kill (unix .Getpid (), syscall .Signal (signal .SIGABRT ))
panic (todo ("unrechable" ))
}
func Xfflush (t *TLS , stream uintptr ) int32 {
return 0
}
func Xfread (t *TLS , ptr uintptr , size , nmemb types .Size_t , stream uintptr ) types .Size_t {
fd := uintptr (file (stream ).fd ())
count := size * nmemb
var n int
var err error
switch {
case count == 0 :
n , err = unix .Read (int (fd ), nil )
default :
n , err = unix .Read (int (fd ), (*RawMem )(unsafe .Pointer (ptr ))[:count :count ])
if dmesgs && err == nil {
dmesg ("%v: fd %v, n %#x\n%s" , origin (1 ), fd , n , hex .Dump ((*RawMem )(unsafe .Pointer (ptr ))[:n :n ]))
}
}
if err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
file (stream ).setErr ()
return types .Size_t (n ) / size
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return types .Size_t (n ) / size
}
func Xfwrite (t *TLS , ptr uintptr , size , nmemb types .Size_t , stream uintptr ) types .Size_t {
fd := uintptr (file (stream ).fd ())
count := size * nmemb
var n int
var err error
switch {
case count == 0 :
n , err = unix .Write (int (fd ), nil )
default :
n , err = unix .Write (int (fd ), (*RawMem )(unsafe .Pointer (ptr ))[:count :count ])
if dmesgs {
dmesg ("%v: fd %v, count %#x\n%s" , origin (1 ), fd , count , hex .Dump ((*RawMem )(unsafe .Pointer (ptr ))[:count :count ]))
}
}
if err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
file (stream ).setErr ()
return types .Size_t (n ) / size
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return types .Size_t (n ) / size
}
func Xfclose (t *TLS , stream uintptr ) int32 {
r := file (stream ).close (t )
if r != 0 {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), r )
}
t .setErrno (r )
return stdio .EOF
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return 0
}
func Xfputc (t *TLS , c int32 , stream uintptr ) int32 {
if _ , err := fwrite (file (stream ).fd (), []byte {byte (c )}); err != nil {
return stdio .EOF
}
return int32 (byte (c ))
}
func Xfseek (t *TLS , stream uintptr , offset long , whence int32 ) int32 {
if n := Xlseek (t , int32 (file (stream ).fd ()), types .Off_t (offset ), whence ); n < 0 {
if dmesgs {
dmesg ("%v: fd %v, off %#x, whence %v: %v" , origin (1 ), file (stream ).fd (), offset , whenceStr (whence ), n )
}
file (stream ).setErr ()
return -1
}
if dmesgs {
dmesg ("%v: fd %v, off %#x, whence %v: ok" , origin (1 ), file (stream ).fd (), offset , whenceStr (whence ))
}
return 0
}
func Xftell (t *TLS , stream uintptr ) long {
n := Xlseek (t , file (stream ).fd (), 0 , stdio .SEEK_CUR )
if n < 0 {
file (stream ).setErr ()
return -1
}
if dmesgs {
dmesg ("%v: fd %v, n %#x: ok %#x" , origin (1 ), file (stream ).fd (), n , long (n ))
}
return long (n )
}
func Xferror (t *TLS , stream uintptr ) int32 {
return Bool32 (file (stream ).err ())
}
func Xfgetc (t *TLS , stream uintptr ) int32 {
panic (todo ("" ))
}
func Xfdopen (t *TLS , fd int32 , mode uintptr ) uintptr {
panic (todo ("" ))
}
func Xfputs (t *TLS , s , stream uintptr ) int32 {
panic (todo ("" ))
}
var getservbynameStaticResult netdb .Servent
func Xgetservbyname (t *TLS , name , proto uintptr ) uintptr {
var protoent *gonetdb .Protoent
if proto != 0 {
protoent = gonetdb .GetProtoByName (GoString (proto ))
}
servent := gonetdb .GetServByName (GoString (name ), protoent )
if servent == nil {
if dmesgs {
dmesg ("%q %q: nil (protoent %+v)" , GoString (name ), GoString (proto ), protoent )
}
return 0
}
Xfree (t , (*netdb .Servent )(unsafe .Pointer (&getservbynameStaticResult )).Fs_name )
if v := (*netdb .Servent )(unsafe .Pointer (&getservbynameStaticResult )).Fs_aliases ; v != 0 {
for {
p := *(*uintptr )(unsafe .Pointer (v ))
if p == 0 {
break
}
Xfree (t , p )
v += unsafe .Sizeof (uintptr (0 ))
}
Xfree (t , v )
}
Xfree (t , (*netdb .Servent )(unsafe .Pointer (&getservbynameStaticResult )).Fs_proto )
cname , err := CString (servent .Name )
if err != nil {
getservbynameStaticResult = netdb .Servent {}
return 0
}
var protoname uintptr
if protoent != nil {
if protoname , err = CString (protoent .Name ); err != nil {
Xfree (t , cname )
getservbynameStaticResult = netdb .Servent {}
return 0
}
}
var a []uintptr
for _ , v := range servent .Aliases {
cs , err := CString (v )
if err != nil {
for _ , v := range a {
Xfree (t , v )
}
return 0
}
a = append (a , cs )
}
v := Xcalloc (t , types .Size_t (len (a )+1 ), types .Size_t (unsafe .Sizeof (uintptr (0 ))))
if v == 0 {
Xfree (t , cname )
Xfree (t , protoname )
for _ , v := range a {
Xfree (t , v )
}
getservbynameStaticResult = netdb .Servent {}
return 0
}
for _ , p := range a {
*(*uintptr )(unsafe .Pointer (v )) = p
v += unsafe .Sizeof (uintptr (0 ))
}
getservbynameStaticResult = netdb .Servent {
Fs_name : cname ,
Fs_aliases : v ,
Fs_port : int32 (servent .Port ),
Fs_proto : protoname ,
}
return uintptr (unsafe .Pointer (&getservbynameStaticResult ))
}
func fcntlCmdStr (cmd int32 ) string {
switch cmd {
case fcntl .F_GETOWN :
return "F_GETOWN"
case fcntl .F_SETLK :
return "F_SETLK"
case fcntl .F_GETLK :
return "F_GETLK"
case fcntl .F_SETFD :
return "F_SETFD"
case fcntl .F_GETFD :
return "F_GETFD"
default :
return fmt .Sprintf ("cmd(%d)" , cmd )
}
}
func Xpread (t *TLS , fd int32 , buf uintptr , count types .Size_t , offset types .Off_t ) types .Ssize_t {
var n int
var err error
switch {
case count == 0 :
n , err = unix .Pread (int (fd ), nil , int64 (offset ))
default :
n , err = unix .Pread (int (fd ), (*RawMem )(unsafe .Pointer (buf ))[:count :count ], int64 (offset ))
if dmesgs && err == nil {
dmesg ("%v: fd %v, off %#x, count %#x, n %#x\n%s" , origin (1 ), fd , offset , count , n , hex .Dump ((*RawMem )(unsafe .Pointer (buf ))[:n :n ]))
}
}
if err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return types .Ssize_t (n )
}
func Xpwrite (t *TLS , fd int32 , buf uintptr , count types .Size_t , offset types .Off_t ) types .Ssize_t {
var n int
var err error
switch {
case count == 0 :
n , err = unix .Pwrite (int (fd ), nil , int64 (offset ))
default :
n , err = unix .Pwrite (int (fd ), (*RawMem )(unsafe .Pointer (buf ))[:count :count ], int64 (offset ))
if dmesgs {
dmesg ("%v: fd %v, off %#x, count %#x\n%s" , origin (1 ), fd , offset , count , hex .Dump ((*RawMem )(unsafe .Pointer (buf ))[:count :count ]))
}
}
if err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return types .Ssize_t (n )
}
func X_NSGetEnviron (t *TLS ) uintptr {
return EnvironP ()
}
func Xchflags (t *TLS , path uintptr , flags uint32 ) int32 {
if err := unix .Chflags (GoString (path ), int (flags )); err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return 0
}
func Xrmdir (t *TLS , pathname uintptr ) int32 {
if err := unix .Rmdir (GoString (pathname )); err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return 0
}
func X__darwin_fd_set (...interface {}) {
panic (todo ("" ))
}
func X__darwin_fd_clr (...interface {}) {
panic (todo ("" ))
}
func X__darwin_fd_isset (...interface {}) int32 {
panic (todo ("" ))
}
func Xmach_absolute_time (t *TLS ) uint64 {
return uint64 (gotime .Now ().UnixNano ())
}
type machTimebaseInfo = struct {
Fnumer uint32
Fdenom uint32
}
func Xmach_timebase_info (t *TLS , info uintptr ) int32 {
*(*machTimebaseInfo )(unsafe .Pointer (info )) = machTimebaseInfo {Fnumer : 1 , Fdenom : 1 }
return 0
}
func Xgetattrlist (t *TLS , path , attrList , attrBuf uintptr , attrBufSize types .Size_t , options uint32 ) int32 {
if _ , _ , err := unix .Syscall6 (unix .SYS_GETATTRLIST , path , attrList , attrBuf , uintptr (attrBufSize ), uintptr (options ), 0 ); err != 0 {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return 0
}
func Xsetattrlist (t *TLS , path , attrList , attrBuf uintptr , attrBufSize types .Size_t , options uint32 ) int32 {
if _ , _ , err := unix .Syscall6 (unix .SYS_SETATTRLIST , path , attrList , attrBuf , uintptr (attrBufSize ), uintptr (options ), 0 ); err != 0 {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
return 0
}
func Xcopyfile (...interface {}) int32 {
panic (todo ("" ))
}
func Xtruncate (...interface {}) int32 {
panic (todo ("" ))
}
type darwinDir struct {
buf [4096 ]byte
fd int
h int
l int
eof bool
}
func Xopendir (t *TLS , name uintptr ) uintptr {
p := Xmalloc (t , uint64 (unsafe .Sizeof (darwinDir {})))
if p == 0 {
panic ("OOM" )
}
fd := int (Xopen (t , name , fcntl .O_RDONLY |fcntl .O_DIRECTORY |fcntl .O_CLOEXEC , 0 ))
if fd < 0 {
if dmesgs {
dmesg ("%v: FAIL %v" , origin (1 ), (*darwinDir )(unsafe .Pointer (p )).fd )
}
Xfree (t , p )
return 0
}
if dmesgs {
dmesg ("%v: ok" , origin (1 ))
}
(*darwinDir )(unsafe .Pointer (p )).fd = fd
(*darwinDir )(unsafe .Pointer (p )).h = 0
(*darwinDir )(unsafe .Pointer (p )).l = 0
(*darwinDir )(unsafe .Pointer (p )).eof = false
return p
}
func Xreaddir (t *TLS , dir uintptr ) uintptr {
if (*darwinDir )(unsafe .Pointer (dir )).eof {
return 0
}
if (*darwinDir )(unsafe .Pointer (dir )).l == (*darwinDir )(unsafe .Pointer (dir )).h {
n , err := unix .Getdirentries ((*darwinDir )(unsafe .Pointer (dir )).fd , (*darwinDir )(unsafe .Pointer (dir )).buf [:], nil )
if n == 0 {
if err != nil && err != io .EOF {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
}
(*darwinDir )(unsafe .Pointer (dir )).eof = true
return 0
}
(*darwinDir )(unsafe .Pointer (dir )).l = 0
(*darwinDir )(unsafe .Pointer (dir )).h = n
}
de := dir + unsafe .Offsetof (darwinDir {}.buf ) + uintptr ((*darwinDir )(unsafe .Pointer (dir )).l )
(*darwinDir )(unsafe .Pointer (dir )).l += int ((*unix .Dirent )(unsafe .Pointer (de )).Reclen )
return de
}
func Xclosedir (t *TLS , dir uintptr ) int32 {
r := Xclose (t , int32 ((*darwinDir )(unsafe .Pointer (dir )).fd ))
Xfree (t , dir )
return r
}
func Xpipe (t *TLS , pipefd uintptr ) int32 {
var a [2 ]int
if err := syscall .Pipe (a [:]); err != nil {
if dmesgs {
dmesg ("%v: %v FAIL" , origin (1 ), err )
}
t .setErrno (err )
return -1
}
*(*[2 ]int32 )(unsafe .Pointer (pipefd )) = [2 ]int32 {int32 (a [0 ]), int32 (a [1 ])}
if dmesgs {
dmesg ("%v: %v ok" , origin (1 ), a )
}
return 0
}
func X__isoc99_sscanf (t *TLS , str , format , va uintptr ) int32 {
r := scanf (strings .NewReader (GoString (str )), format , va )
return r
}
func Xsscanf (t *TLS , str , format , va uintptr ) int32 {
r := scanf (strings .NewReader (GoString (str )), format , va )
return r
}
The pages are generated with Golds v0.3.6 . (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .