summaryrefslogtreecommitdiff
path: root/vendor/modernc.org/libc/libc_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/modernc.org/libc/libc_linux.go')
-rw-r--r--vendor/modernc.org/libc/libc_linux.go239
1 files changed, 175 insertions, 64 deletions
diff --git a/vendor/modernc.org/libc/libc_linux.go b/vendor/modernc.org/libc/libc_linux.go
index aaec3da68..991a98c8e 100644
--- a/vendor/modernc.org/libc/libc_linux.go
+++ b/vendor/modernc.org/libc/libc_linux.go
@@ -6,18 +6,22 @@ package libc // import "modernc.org/libc"
import (
"bufio"
+ "encoding/hex"
"fmt"
+ "math"
+ "math/rand"
"os"
"os/exec"
"path/filepath"
- "runtime"
"runtime/debug"
"strconv"
"strings"
+ "sync"
"syscall"
"time"
"unsafe"
+ guuid "github.com/google/uuid"
"golang.org/x/sys/unix"
"modernc.org/libc/errno"
"modernc.org/libc/fcntl"
@@ -31,16 +35,19 @@ import (
"modernc.org/libc/pwd"
"modernc.org/libc/signal"
"modernc.org/libc/stdio"
+ "modernc.org/libc/stdlib"
"modernc.org/libc/sys/socket"
"modernc.org/libc/sys/stat"
"modernc.org/libc/sys/types"
"modernc.org/libc/termios"
ctime "modernc.org/libc/time"
"modernc.org/libc/unistd"
+ "modernc.org/libc/uuid/uuid"
)
var (
in6_addr_any in.In6_addr
+ _ = X__ctype_b_loc
)
type (
@@ -69,6 +76,7 @@ func newFile(t *TLS, fd int32) uintptr {
if p == 0 {
return 0
}
+
file(p).setFd(fd)
return p
}
@@ -106,46 +114,6 @@ func Xgetrusage(t *TLS, who int32, usage uintptr) int32 {
return 0
}
-// char *fgets(char *s, int size, FILE *stream);
-func Xfgets(t *TLS, s uintptr, size int32, stream uintptr) uintptr {
- fd := int((*stdio.FILE)(unsafe.Pointer(stream)).F_fileno)
- 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(""))
- }
-
- // if err == nil {
- // panic("internal error")
- // }
-
- // if len(b) != 0 {
- // b = append(b, 0)
- // copy((*RawMem)(unsafe.Pointer(s)[:len(b)]), b)
- // return s
- // }
-
- // t.setErrno(err)
- }
- panic(todo(""))
-}
-
// int lstat(const char *pathname, struct stat *statbuf);
func Xlstat(t *TLS, pathname, statbuf uintptr) int32 {
return Xlstat64(t, pathname, statbuf)
@@ -223,7 +191,7 @@ func Xopen64(t *TLS, pathname uintptr, flags int32, args uintptr) int32 {
//TODO- flags |= fcntl.O_LARGEFILE
var mode types.Mode_t
if args != 0 {
- mode = *(*types.Mode_t)(unsafe.Pointer(args))
+ mode = (types.Mode_t)(VaUint32(&args))
}
fdcwd := fcntl.AT_FDCWD
n, _, err := unix.Syscall6(unix.SYS_OPENAT, uintptr(fdcwd), pathname, uintptr(flags|unix.O_LARGEFILE), uintptr(mode), 0, 0)
@@ -1264,7 +1232,27 @@ func Xmkstemps64(t *TLS, template uintptr, suffixlen int32) int32 {
}
}
- fd, err := tempFile(template, x)
+ fd, err := tempFile(template, x, 0)
+ if err != 0 {
+ t.setErrno(err)
+ return -1
+ }
+
+ return int32(fd)
+}
+
+// int mkostemp(char *template, int flags);
+func Xmkostemp(t *TLS, template uintptr, flags int32) int32 {
+ len := uintptr(Xstrlen(t, template))
+ x := template + uintptr(len-6)
+ for i := uintptr(0); i < 6; i++ {
+ if *(*byte)(unsafe.Pointer(x + i)) != 'X' {
+ t.setErrno(errno.EINVAL)
+ return -1
+ }
+ }
+
+ fd, err := tempFile(template, x, flags)
if err != 0 {
t.setErrno(err)
return -1
@@ -1493,9 +1481,14 @@ func Xstrerror(t *TLS, errnum int32) uintptr {
return uintptr(unsafe.Pointer(&strerrorBuf[0]))
}
+// int strerror_r(int errnum, char *buf, size_t buflen);
+func Xstrerror_r(t *TLS, errnum int32, buf uintptr, buflen size_t) int32 {
+ panic(todo(""))
+}
+
// void *dlopen(const char *filename, int flags);
func Xdlopen(t *TLS, filename uintptr, flags int32) uintptr {
- panic(todo(""))
+ panic(todo("%q", GoString(filename)))
}
// char *dlerror(void);
@@ -1723,16 +1716,6 @@ func Xferror(t *TLS, stream uintptr) int32 {
return Bool32(file(stream).err())
}
-// int fgetc(FILE *stream);
-func Xfgetc(t *TLS, stream uintptr) int32 {
- panic(todo(""))
-}
-
-// int getc(FILE *stream);
-func Xgetc(t *TLS, stream uintptr) int32 {
- return Xfgetc(t, stream)
-}
-
// int ungetc(int c, FILE *stream);
func Xungetc(t *TLS, c int32, stream uintptr) int32 {
panic(todo(""))
@@ -1743,11 +1726,6 @@ func Xfscanf(t *TLS, stream, format, va uintptr) int32 {
panic(todo(""))
}
-// FILE *fdopen(int fd, const char *mode);
-func Xfdopen(t *TLS, fd int32, mode uintptr) uintptr {
- panic(todo(""))
-}
-
// int fputs(const char *s, FILE *stream);
func Xfputs(t *TLS, s, stream uintptr) int32 {
if _, _, err := unix.Syscall(unix.SYS_WRITE, uintptr(file(stream).fd()), s, uintptr(Xstrlen(t, s))); err != 0 {
@@ -1944,11 +1922,6 @@ func X__isoc99_sscanf(t *TLS, str, format, va uintptr) int32 {
return r
}
-// int sched_yield(void);
-func Xsched_yield(t *TLS) {
- runtime.Gosched()
-}
-
var ctimeStaticBuf [32]byte
// char *ctime(const time_t *timep);
@@ -1964,3 +1937,141 @@ func Xctime_r(t *TLS, timep, buf uintptr) uintptr {
copy((*RawMem)(unsafe.Pointer(buf))[:26:26], s)
return buf
}
+
+// ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
+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)
+}
+
+// int fstatfs(int fd, struct statfs *buf);
+func Xfstatfs(t *TLS, fd int32, buf uintptr) int32 {
+ if err := unix.Fstatfs(int(fd), (*unix.Statfs_t)(unsafe.Pointer(buf))); err != nil {
+ t.setErrno(err)
+ return -1
+ }
+
+ return 0
+}
+
+// ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);
+func Xgetrandom(t *TLS, buf uintptr, buflen size_t, flags uint32) ssize_t {
+ n, err := unix.Getrandom((*RawMem)(unsafe.Pointer(buf))[:buflen], int(flags))
+ if err != nil {
+ t.setErrno(err)
+ return -1
+ }
+
+ return ssize_t(n)
+}
+
+// int posix_fadvise(int fd, off_t offset, off_t len, int advice);
+func Xposix_fadvise(t *TLS, fd int32, offset, len types.Off_t, advice int32) int32 {
+ if err := unix.Fadvise(int(fd), int64(offset), int64(len), int(advice)); err != nil {
+ return int32(err.(unix.Errno))
+ }
+
+ return 0
+}
+
+// void uuid_generate_random(uuid_t out);
+func Xuuid_generate_random(t *TLS, out uintptr) {
+ panic(todo(""))
+}
+
+// void uuid_unparse(uuid_t uu, char *out);
+func Xuuid_unparse(t *TLS, uu, out uintptr) {
+ s := (*guuid.UUID)(unsafe.Pointer(uu)).String()
+ copy((*RawMem)(unsafe.Pointer(out))[:], s)
+ *(*byte)(unsafe.Pointer(out + uintptr(len(s)))) = 0
+}
+
+// int uuid_parse( char *in, uuid_t uu);
+func Xuuid_parse(t *TLS, in uintptr, uu uintptr) int32 {
+ r, err := guuid.Parse(GoString(in))
+ if err != nil {
+ return -1
+ }
+
+ copy((*RawMem)(unsafe.Pointer(uu))[:unsafe.Sizeof(uuid.Uuid_t{})], r[:])
+ return 0
+}
+
+// The initstate_r() function is like initstate(3) except that it initializes
+// the state in the object pointed to by buf, rather than initializing the
+// global state variable. Before calling this function, the buf.state field
+// must be initialized to NULL. The initstate_r() function records a pointer
+// to the statebuf argument inside the structure pointed to by buf. Thus,
+// state‐ buf should not be deallocated so long as buf is still in use. (So,
+// statebuf should typically be allocated as a static variable, or allocated on
+// the heap using malloc(3) or similar.)
+//
+// char *initstate_r(unsigned int seed, char *statebuf, size_t statelen, struct random_data *buf);
+func Xinitstate_r(t *TLS, seed uint32, statebuf uintptr, statelen types.Size_t, buf uintptr) int32 {
+ if buf == 0 {
+ panic(todo(""))
+ }
+
+ randomDataMu.Lock()
+
+ defer randomDataMu.Unlock()
+
+ randomData[buf] = rand.New(rand.NewSource(int64(seed)))
+ return 0
+}
+
+var (
+ randomData = map[uintptr]*rand.Rand{}
+ randomDataMu sync.Mutex
+)
+
+// int random_r(struct random_data *buf, int32_t *result);
+func Xrandom_r(t *TLS, buf, result uintptr) int32 {
+ randomDataMu.Lock()
+
+ defer randomDataMu.Unlock()
+
+ mr := randomData[buf]
+ if stdlib.RAND_MAX != math.MaxInt32 {
+ panic(todo(""))
+ }
+ *(*int32)(unsafe.Pointer(result)) = mr.Int31()
+ return 0
+}
+
+// void uuid_copy(uuid_t dst, uuid_t src);
+func Xuuid_copy(t *TLS, dst, src uintptr) {
+ *(*uuid.Uuid_t)(unsafe.Pointer(dst)) = *(*uuid.Uuid_t)(unsafe.Pointer(src))
+}
+
+// int fgetc(FILE *stream);
+func Xfgetc(t *TLS, stream uintptr) int32 {
+ fd := int((*stdio.FILE)(unsafe.Pointer(stream)).F_fileno)
+ var buf [1]byte
+ if n, _ := unix.Read(fd, buf[:]); n != 0 {
+ return int32(buf[0])
+ }
+
+ return stdio.EOF
+}