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

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