modernc.org/libc@v1.24.1/libc_linux_arm64.go (about)

     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  }
   440  
   441  // int setrlimit(int resource, const struct rlimit *rlim);
   442  func Xsetrlimit64(t *TLS, resource int32, rlim uintptr) int32 {
   443  	if _, _, err := unix.Syscall(unix.SYS_SETRLIMIT, uintptr(resource), uintptr(rlim), 0); err != 0 {
   444  		t.setErrno(err)
   445  		return -1
   446  	}
   447  
   448  	return 0
   449  }