gtsocial-umbx

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

libc_linux_arm64.go (11175B)


      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 	"os"
      9 	"strings"
     10 	"time"
     11 	"unsafe"
     12 
     13 	"golang.org/x/sys/unix"
     14 	"modernc.org/libc/errno"
     15 	"modernc.org/libc/fcntl"
     16 	"modernc.org/libc/signal"
     17 	"modernc.org/libc/sys/stat"
     18 	"modernc.org/libc/sys/types"
     19 )
     20 
     21 // int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
     22 func Xsigaction(t *TLS, signum int32, act, oldact uintptr) int32 {
     23 	// 	musl/src/internal/ksigaction.h
     24 	//
     25 	//	struct k_sigaction {
     26 	//		void (*handler)(int);
     27 	//		unsigned long flags;
     28 	//		void (*restorer)(void);
     29 	//		unsigned mask[2];
     30 	//	};
     31 	type k_sigaction struct {
     32 		handler  uintptr
     33 		flags    ulong
     34 		restorer uintptr
     35 		mask     [2]uint32
     36 	}
     37 
     38 	var kact, koldact uintptr
     39 	if act != 0 {
     40 		sz := int(unsafe.Sizeof(k_sigaction{}))
     41 		kact = t.Alloc(sz)
     42 		defer t.Free(sz)
     43 		*(*k_sigaction)(unsafe.Pointer(kact)) = k_sigaction{
     44 			handler:  (*signal.Sigaction)(unsafe.Pointer(act)).F__sigaction_handler.Fsa_handler,
     45 			flags:    ulong((*signal.Sigaction)(unsafe.Pointer(act)).Fsa_flags),
     46 			restorer: (*signal.Sigaction)(unsafe.Pointer(act)).Fsa_restorer,
     47 		}
     48 		Xmemcpy(t, kact+unsafe.Offsetof(k_sigaction{}.mask), act+unsafe.Offsetof(signal.Sigaction{}.Fsa_mask), types.Size_t(unsafe.Sizeof(k_sigaction{}.mask)))
     49 	}
     50 	if oldact != 0 {
     51 		panic(todo(""))
     52 	}
     53 
     54 	if _, _, err := unix.Syscall6(unix.SYS_RT_SIGACTION, uintptr(signum), kact, koldact, unsafe.Sizeof(k_sigaction{}.mask), 0, 0); err != 0 {
     55 		t.setErrno(err)
     56 		return -1
     57 	}
     58 
     59 	if oldact != 0 {
     60 		panic(todo(""))
     61 	}
     62 
     63 	return 0
     64 }
     65 
     66 // int lstat(const char *pathname, struct stat *statbuf);
     67 func Xlstat64(t *TLS, pathname, statbuf uintptr) int32 {
     68 	if err := unix.Lstat(GoString(pathname), (*unix.Stat_t)(unsafe.Pointer(statbuf))); err != nil {
     69 		if dmesgs {
     70 			dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
     71 		}
     72 		t.setErrno(err)
     73 		return -1
     74 	}
     75 
     76 	if dmesgs {
     77 		dmesg("%v: %q: ok", origin(1), GoString(pathname))
     78 	}
     79 	return 0
     80 }
     81 
     82 // int stat(const char *pathname, struct stat *statbuf);
     83 func Xstat64(t *TLS, pathname, statbuf uintptr) int32 {
     84 	if err := unix.Fstatat(unix.AT_FDCWD, GoString(pathname), (*unix.Stat_t)(unsafe.Pointer(statbuf)), 0); err != nil {
     85 		if dmesgs {
     86 			dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
     87 		}
     88 		t.setErrno(err)
     89 		return -1
     90 	}
     91 
     92 	if dmesgs {
     93 		dmesg("%v: %q: ok", origin(1), GoString(pathname))
     94 	}
     95 	return 0
     96 }
     97 
     98 // int unlink(const char *pathname);
     99 func Xunlink(t *TLS, pathname uintptr) int32 {
    100 	if err := unix.Unlinkat(unix.AT_FDCWD, GoString(pathname), 0); err != nil {
    101 		t.setErrno(err)
    102 		return -1
    103 	}
    104 
    105 	if dmesgs {
    106 		dmesg("%v: %q: ok", origin(1), GoString(pathname))
    107 	}
    108 	return 0
    109 }
    110 
    111 // int access(const char *pathname, int mode);
    112 func Xaccess(t *TLS, pathname uintptr, mode int32) int32 {
    113 	if err := unix.Faccessat(unix.AT_FDCWD, GoString(pathname), uint32(mode), 0); err != nil {
    114 		if dmesgs {
    115 			dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
    116 		}
    117 		t.setErrno(err)
    118 		return -1
    119 	}
    120 
    121 	if dmesgs {
    122 		dmesg("%v: %q %#o: ok", origin(1), GoString(pathname), mode)
    123 	}
    124 	return 0
    125 }
    126 
    127 // off64_t lseek64(int fd, off64_t offset, int whence);
    128 func Xlseek64(t *TLS, fd int32, offset types.Off_t, whence int32) types.Off_t {
    129 	n, _, err := unix.Syscall(unix.SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
    130 	if err != 0 {
    131 		if dmesgs {
    132 			dmesg("%v: fd %v, off %#x, whence %v: %v", origin(1), fd, offset, whenceStr(whence), err)
    133 		}
    134 		t.setErrno(err)
    135 		return -1
    136 	}
    137 
    138 	if dmesgs {
    139 		dmesg("%v: fd %v, off %#x, whence %v: %#x", origin(1), fd, offset, whenceStr(whence), n)
    140 	}
    141 	return types.Off_t(n)
    142 }
    143 
    144 // int fstat(int fd, struct stat *statbuf);
    145 func Xfstat64(t *TLS, fd int32, statbuf uintptr) int32 {
    146 	if _, _, err := unix.Syscall(unix.SYS_FSTAT, uintptr(fd), statbuf, 0); err != 0 {
    147 		if dmesgs {
    148 			dmesg("%v: fd %d: %v", origin(1), fd, err)
    149 		}
    150 		t.setErrno(err)
    151 		return -1
    152 	}
    153 
    154 	if dmesgs {
    155 		dmesg("%v: %d size %#x: ok\n%+v", origin(1), fd, (*stat.Stat)(unsafe.Pointer(statbuf)).Fst_size, (*stat.Stat)(unsafe.Pointer(statbuf)))
    156 	}
    157 	return 0
    158 }
    159 
    160 // int ftruncate(int fd, off_t length);
    161 func Xftruncate64(t *TLS, fd int32, length types.Off_t) int32 {
    162 	if _, _, err := unix.Syscall(unix.SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0); err != 0 {
    163 		if dmesgs {
    164 			dmesg("%v: fd %d: %v", origin(1), fd, err)
    165 		}
    166 		t.setErrno(err)
    167 		return -1
    168 	}
    169 
    170 	if dmesgs {
    171 		dmesg("%v: %d %#x: ok", origin(1), fd, length)
    172 	}
    173 	return 0
    174 }
    175 
    176 // int fcntl(int fd, int cmd, ... /* arg */ );
    177 func Xfcntl64(t *TLS, fd, cmd int32, args uintptr) int32 {
    178 	var arg uintptr
    179 	if args != 0 {
    180 		arg = *(*uintptr)(unsafe.Pointer(args))
    181 	}
    182 	if cmd == fcntl.F_SETFL {
    183 		arg |= unix.O_LARGEFILE
    184 	}
    185 	n, _, err := unix.Syscall(unix.SYS_FCNTL, uintptr(fd), uintptr(cmd), arg)
    186 	if err != 0 {
    187 		if dmesgs {
    188 			dmesg("%v: fd %v cmd %v", origin(1), fcntlCmdStr(fd), cmd)
    189 		}
    190 		t.setErrno(err)
    191 		return -1
    192 	}
    193 
    194 	if dmesgs {
    195 		dmesg("%v: %d %s %#x: %d", origin(1), fd, fcntlCmdStr(cmd), arg, n)
    196 	}
    197 	return int32(n)
    198 }
    199 
    200 // int rmdir(const char *pathname);
    201 func Xrmdir(t *TLS, pathname uintptr) int32 {
    202 	if err := unix.Rmdir(GoString(pathname)); err != nil {
    203 		t.setErrno(err)
    204 		return -1
    205 	}
    206 
    207 	if dmesgs {
    208 		dmesg("%v: %q: ok", origin(1), GoString(pathname))
    209 	}
    210 	return 0
    211 }
    212 
    213 // int rename(const char *oldpath, const char *newpath);
    214 func Xrename(t *TLS, oldpath, newpath uintptr) int32 {
    215 	if err := unix.Rename(GoString(oldpath), GoString(newpath)); err != nil {
    216 		t.setErrno(err)
    217 		return -1
    218 	}
    219 
    220 	return 0
    221 }
    222 
    223 // int mknod(const char *pathname, mode_t mode, dev_t dev);
    224 func Xmknod(t *TLS, pathname uintptr, mode types.Mode_t, dev types.Dev_t) int32 {
    225 	panic(todo(""))
    226 }
    227 
    228 // int chown(const char *pathname, uid_t owner, gid_t group);
    229 func Xchown(t *TLS, pathname uintptr, owner types.Uid_t, group types.Gid_t) int32 {
    230 	if err := unix.Chown(GoString(pathname), int(owner), int(group)); err != nil {
    231 		t.setErrno(err)
    232 		return -1
    233 	}
    234 
    235 	return 0
    236 }
    237 
    238 // int link(const char *oldpath, const char *newpath);
    239 func Xlink(t *TLS, oldpath, newpath uintptr) int32 {
    240 	panic(todo(""))
    241 }
    242 
    243 // int pipe(int pipefd[2]);
    244 func Xpipe(t *TLS, pipefd uintptr) int32 {
    245 	if _, _, err := unix.Syscall(unix.SYS_PIPE2, pipefd, 0, 0); err != 0 {
    246 		t.setErrno(err)
    247 		return -1
    248 	}
    249 
    250 	return 0
    251 }
    252 
    253 // int dup2(int oldfd, int newfd);
    254 func Xdup2(t *TLS, oldfd, newfd int32) int32 {
    255 	panic(todo(""))
    256 }
    257 
    258 // int getrlimit(int resource, struct rlimit *rlim);
    259 func Xgetrlimit64(t *TLS, resource int32, rlim uintptr) int32 {
    260 	if _, _, err := unix.Syscall(unix.SYS_GETRLIMIT, uintptr(resource), uintptr(rlim), 0); err != 0 {
    261 		t.setErrno(err)
    262 		return -1
    263 	}
    264 
    265 	return 0
    266 }
    267 
    268 // ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);
    269 func Xreadlink(t *TLS, path, buf uintptr, bufsize types.Size_t) types.Ssize_t {
    270 	n, err := unix.Readlink(GoString(path), GoBytes(buf, int(bufsize)))
    271 	if err != nil {
    272 		t.setErrno(err)
    273 		return -1
    274 	}
    275 
    276 	return types.Ssize_t(n)
    277 }
    278 
    279 // FILE *fopen64(const char *pathname, const char *mode);
    280 func Xfopen64(t *TLS, pathname, mode uintptr) uintptr {
    281 	m := strings.ReplaceAll(GoString(mode), "b", "")
    282 	var flags int
    283 	switch m {
    284 	case "r":
    285 		flags = os.O_RDONLY
    286 	case "r+":
    287 		flags = os.O_RDWR
    288 	case "w":
    289 		flags = os.O_WRONLY | os.O_CREATE | os.O_TRUNC
    290 	case "w+":
    291 		flags = os.O_RDWR | os.O_CREATE | os.O_TRUNC
    292 	case "a":
    293 		flags = os.O_WRONLY | os.O_CREATE | os.O_APPEND
    294 	case "a+":
    295 		flags = os.O_RDWR | os.O_CREATE | os.O_APPEND
    296 	default:
    297 		panic(m)
    298 	}
    299 	//TODO- flags |= fcntl.O_LARGEFILE
    300 	fd, err := unix.Openat(unix.AT_FDCWD, GoString(pathname), flags, 0666)
    301 	if err != nil {
    302 		t.setErrno(err)
    303 		return 0
    304 	}
    305 
    306 	if p := newFile(t, int32(fd)); p != 0 {
    307 		return p
    308 	}
    309 
    310 	Xclose(t, int32(fd))
    311 	t.setErrno(errno.ENOMEM)
    312 	return 0
    313 }
    314 
    315 // int mkdir(const char *path, mode_t mode);
    316 func Xmkdir(t *TLS, path uintptr, mode types.Mode_t) int32 {
    317 	if err := unix.Mkdir(GoString(path), uint32(mode)); err != nil {
    318 		t.setErrno(err)
    319 		return -1
    320 	}
    321 
    322 	if dmesgs {
    323 		dmesg("%v: %q: ok", origin(1), GoString(path))
    324 	}
    325 	return 0
    326 }
    327 
    328 // void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, ... /* void *new_address */);
    329 func Xmremap(t *TLS, old_address uintptr, old_size, new_size types.Size_t, flags int32, args uintptr) uintptr {
    330 	var arg uintptr
    331 	if args != 0 {
    332 		arg = *(*uintptr)(unsafe.Pointer(args))
    333 	}
    334 	data, _, err := unix.Syscall6(unix.SYS_MREMAP, old_address, uintptr(old_size), uintptr(new_size), uintptr(flags), arg, 0)
    335 	if err != 0 {
    336 		if dmesgs {
    337 			dmesg("%v: %v", origin(1), err)
    338 		}
    339 		t.setErrno(err)
    340 		return ^uintptr(0) // (void*)-1
    341 	}
    342 
    343 	if dmesgs {
    344 		dmesg("%v: %#x", origin(1), data)
    345 	}
    346 	return data
    347 }
    348 
    349 func Xmmap(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr {
    350 	return Xmmap64(t, addr, length, prot, flags, fd, offset)
    351 }
    352 
    353 // void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
    354 func Xmmap64(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr {
    355 	data, _, err := unix.Syscall6(unix.SYS_MMAP, addr, uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
    356 	if err != 0 {
    357 		if dmesgs {
    358 			dmesg("%v: %v", origin(1), err)
    359 		}
    360 		t.setErrno(err)
    361 		return ^uintptr(0) // (void*)-1
    362 	}
    363 
    364 	if dmesgs {
    365 		dmesg("%v: %#x", origin(1), data)
    366 	}
    367 	return data
    368 }
    369 
    370 // int symlink(const char *target, const char *linkpath);
    371 func Xsymlink(t *TLS, target, linkpath uintptr) int32 {
    372 	if err := unix.Symlink(GoString(target), GoString(linkpath)); err != nil {
    373 		t.setErrno(err)
    374 		return -1
    375 	}
    376 
    377 	if dmesgs {
    378 		dmesg("%v: %q %q: ok", origin(1), GoString(target), GoString(linkpath))
    379 	}
    380 	return 0
    381 }
    382 
    383 // int chmod(const char *pathname, mode_t mode)
    384 func Xchmod(t *TLS, pathname uintptr, mode types.Mode_t) int32 {
    385 	if err := unix.Chmod(GoString(pathname), uint32(mode)); err != nil {
    386 		t.setErrno(err)
    387 		return -1
    388 	}
    389 
    390 	if dmesgs {
    391 		dmesg("%v: %q %#o: ok", origin(1), GoString(pathname), mode)
    392 	}
    393 	return 0
    394 }
    395 
    396 // time_t time(time_t *tloc);
    397 func Xtime(t *TLS, tloc uintptr) types.Time_t {
    398 	n := time.Now().UTC().Unix()
    399 	if tloc != 0 {
    400 		*(*types.Time_t)(unsafe.Pointer(tloc)) = types.Time_t(n)
    401 	}
    402 	return types.Time_t(n)
    403 }
    404 
    405 // int utimes(const char *filename, const struct timeval times[2]);
    406 func Xutimes(t *TLS, filename, times uintptr) int32 {
    407 	var tv []unix.Timeval
    408 	if times != 0 {
    409 		tv = make([]unix.Timeval, 2)
    410 		*(*[2]unix.Timeval)(unsafe.Pointer(&tv[0])) = *(*[2]unix.Timeval)(unsafe.Pointer(times))
    411 	}
    412 	if err := unix.Utimes(GoString(filename), tv); err != nil {
    413 		t.setErrno(err)
    414 		return -1
    415 	}
    416 
    417 	if times != 0 {
    418 		*(*[2]unix.Timeval)(unsafe.Pointer(times)) = *(*[2]unix.Timeval)(unsafe.Pointer(&tv[0]))
    419 	}
    420 	if dmesgs {
    421 		dmesg("%v: %q: ok", origin(1), GoString(filename))
    422 	}
    423 	return 0
    424 }
    425 
    426 // int utime(const char *filename, const struct utimbuf *times);
    427 func Xutime(t *TLS, filename, times uintptr) int32 {
    428 	if err := unix.Utime(GoString(filename), (*unix.Utimbuf)(unsafe.Pointer(times))); err != nil {
    429 		t.setErrno(err)
    430 		return -1
    431 	}
    432 
    433 	return 0
    434 }
    435 
    436 // unsigned int alarm(unsigned int seconds);
    437 func Xalarm(t *TLS, seconds uint32) uint32 {
    438 	panic(todo(""))
    439 }