^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/falloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sys/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sys/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sys/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sys/sysmacros.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sys/un.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sys/eventfd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <os.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static void copy_stat(struct uml_stat *dst, const struct stat64 *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *dst = ((struct uml_stat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .ust_dev = src->st_dev, /* device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .ust_ino = src->st_ino, /* inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .ust_mode = src->st_mode, /* protection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .ust_nlink = src->st_nlink, /* number of hard links */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .ust_uid = src->st_uid, /* user ID of owner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .ust_gid = src->st_gid, /* group ID of owner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .ust_size = src->st_size, /* total size, in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .ust_blocks = src->st_blocks, /* number of blocks allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .ust_atime = src->st_atime, /* time of last access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .ust_mtime = src->st_mtime, /* time of last modification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .ust_ctime = src->st_ctime, /* time of last change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) });
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int os_stat_fd(const int fd, struct uml_stat *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct stat64 sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) CATCH_EINTR(err = fstat64(fd, &sbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (ubuf != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) copy_stat(ubuf, &sbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int os_stat_file(const char *file_name, struct uml_stat *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct stat64 sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) CATCH_EINTR(err = stat64(file_name, &sbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (ubuf != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) copy_stat(ubuf, &sbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int os_access(const char *file, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int amode, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) amode = (mode & OS_ACC_R_OK ? R_OK : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) (mode & OS_ACC_W_OK ? W_OK : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) (mode & OS_ACC_X_OK ? X_OK : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) (mode & OS_ACC_F_OK ? F_OK : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) err = access(file, amode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) err = ioctl(fd, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* FIXME: ensure namebuf in os_get_if_name is big enough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int os_get_ifname(int fd, char* namebuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (ioctl(fd, SIOCGIFNAME, namebuf) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int os_set_slip(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int disc, sencap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) disc = N_SLIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (ioctl(fd, TIOCSETD, &disc) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) sencap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (ioctl(fd, SIOCSIFENCAP, &sencap) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int os_mode_fd(int fd, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) CATCH_EINTR(err = fchmod(fd, mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int os_file_type(char *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct uml_stat buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) err = os_stat_file(file, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (S_ISDIR(buf.ust_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return OS_TYPE_DIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) else if (S_ISLNK(buf.ust_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return OS_TYPE_SYMLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) else if (S_ISCHR(buf.ust_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return OS_TYPE_CHARDEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) else if (S_ISBLK(buf.ust_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return OS_TYPE_BLOCKDEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) else if (S_ISFIFO(buf.ust_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return OS_TYPE_FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) else if (S_ISSOCK(buf.ust_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return OS_TYPE_SOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) else return OS_TYPE_FILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int os_file_mode(const char *file, struct openflags *mode_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *mode_out = OPENFLAGS();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) err = access(file, W_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (err && (errno != EACCES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) else if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) *mode_out = of_write(*mode_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) err = access(file, R_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (err && (errno != EACCES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) else if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) *mode_out = of_read(*mode_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int os_open_file(const char *file, struct openflags flags, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int fd, err, f = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (flags.r && flags.w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) f = O_RDWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) else if (flags.r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) f = O_RDONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) else if (flags.w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) f = O_WRONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) else f = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (flags.s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) f |= O_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (flags.c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) f |= O_CREAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (flags.t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) f |= O_TRUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (flags.e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) f |= O_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (flags.a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) f |= O_APPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) fd = open64(file, f, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (flags.cl && fcntl(fd, F_SETFD, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int os_connect_socket(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct sockaddr_un sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int fd, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) sock.sun_family = AF_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) fd = socket(AF_UNIX, SOCK_STREAM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) out_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) void os_close_file(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int os_fsync_file(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (fsync(fd) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int os_seek_file(int fd, unsigned long long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) unsigned long long actual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) actual = lseek64(fd, offset, SEEK_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (actual != offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int os_read_file(int fd, void *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int n = read(fd, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int os_pread_file(int fd, void *buf, int len, unsigned long long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int n = pread(fd, buf, len, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int os_write_file(int fd, const void *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int n = write(fd, (void *) buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int os_sync_file(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int n = fdatasync(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int os_pwrite_file(int fd, const void *buf, int len, unsigned long long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int n = pwrite(fd, (void *) buf, len, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int os_file_size(const char *file, unsigned long long *size_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct uml_stat buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) err = os_stat_file(file, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (S_ISBLK(buf.ust_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) long blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) fd = open(file, O_RDONLY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) printk(UM_KERN_ERR "Couldn't open \"%s\", "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) "errno = %d\n", file, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (ioctl(fd, BLKGETSIZE, &blocks) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) printk(UM_KERN_ERR "Couldn't get the block size of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) "\"%s\", errno = %d\n", file, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *size_out = ((long long) blocks) * 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) else *size_out = buf.ust_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int os_file_modtime(const char *file, long long *modtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct uml_stat buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) err = os_stat_file(file, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *modtime = buf.ust_mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) int os_set_exec_close(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int os_pipe(int *fds, int stream, int close_on_exec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) err = socketpair(AF_UNIX, type, 0, fds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!close_on_exec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) err = os_set_exec_close(fds[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) err = os_set_exec_close(fds[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) printk(UM_KERN_ERR "os_pipe : Setting FD_CLOEXEC failed, err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) close(fds[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) close(fds[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int os_set_fd_async(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int err, flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) flags = fcntl(fd, F_GETFL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (flags < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) flags |= O_ASYNC | O_NONBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (fcntl(fd, F_SETFL, flags) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) printk(UM_KERN_ERR "os_set_fd_async : failed to set O_ASYNC "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) "and O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if ((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) (fcntl(fd, F_SETOWN, os_getpid()) < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) printk(UM_KERN_ERR "os_set_fd_async : Failed to fcntl F_SETOWN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) "(or F_SETSIG) fd %d, errno = %d\n", fd, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int os_clear_fd_async(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) flags = fcntl(fd, F_GETFL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (flags < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) flags &= ~(O_ASYNC | O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (fcntl(fd, F_SETFL, flags) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int os_set_fd_block(int fd, int blocking)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) flags = fcntl(fd, F_GETFL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (flags < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (blocking)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) flags &= ~O_NONBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) flags |= O_NONBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (fcntl(fd, F_SETFL, flags) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int os_accept_connection(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) new = accept(fd, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (new < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) #ifndef SHUT_RD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) #define SHUT_RD 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) #ifndef SHUT_WR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) #define SHUT_WR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) #ifndef SHUT_RDWR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #define SHUT_RDWR 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int os_shutdown_socket(int fd, int r, int w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int what, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (r && w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) what = SHUT_RDWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) else if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) what = SHUT_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) else if (w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) what = SHUT_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) err = shutdown(fd, what);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) int os_rcv_fd(int fd, int *helper_pid_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int new, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) char buf[CMSG_SPACE(sizeof(new))];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct msghdr msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct cmsghdr *cmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct iovec iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) msg.msg_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) msg.msg_namelen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) iov = ((struct iovec) { .iov_base = helper_pid_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .iov_len = sizeof(*helper_pid_out) });
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) msg.msg_iov = &iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) msg.msg_iovlen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) msg.msg_control = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) msg.msg_controllen = sizeof(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) msg.msg_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) n = recvmsg(fd, &msg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) else if (n != iov.iov_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) *helper_pid_out = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) cmsg = CMSG_FIRSTHDR(&msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (cmsg == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) printk(UM_KERN_ERR "rcv_fd didn't receive anything, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) "error = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if ((cmsg->cmsg_level != SOL_SOCKET) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) (cmsg->cmsg_type != SCM_RIGHTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) printk(UM_KERN_ERR "rcv_fd didn't receive a descriptor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) new = ((int *) CMSG_DATA(cmsg))[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int os_create_unix_socket(const char *file, int len, int close_on_exec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct sockaddr_un addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int sock, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) sock = socket(PF_UNIX, SOCK_DGRAM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (sock < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (close_on_exec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) err = os_set_exec_close(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) printk(UM_KERN_ERR "create_unix_socket : "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) "close_on_exec failed, err = %d", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) addr.sun_family = AF_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) snprintf(addr.sun_path, len, "%s", file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) void os_flush_stdout(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) fflush(stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int os_lock_file(int fd, int excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int type = excl ? F_WRLCK : F_RDLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct flock lock = ((struct flock) { .l_type = type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .l_whence = SEEK_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .l_start = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .l_len = 0 } );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int err, save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) err = fcntl(fd, F_SETLK, &lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) save = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) err = fcntl(fd, F_GETLK, &lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) printk(UM_KERN_ERR "F_SETLK failed, file already locked by pid %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) lock.l_pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) err = save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) unsigned os_major(unsigned long long dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return major(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) unsigned os_minor(unsigned long long dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return minor(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) unsigned long long os_makedev(unsigned major, unsigned minor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return makedev(major, minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) int os_falloc_punch(int fd, unsigned long long offset, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) int n = fallocate(fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int os_eventfd(unsigned int initval, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) int fd = eventfd(initval, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) int os_sendmsg_fds(int fd, const void *buf, unsigned int len, const int *fds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) unsigned int fds_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct iovec iov = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .iov_base = (void *) buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .iov_len = len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) char control[CMSG_SPACE(sizeof(*fds) * OS_SENDMSG_MAX_FDS)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct cmsghdr align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) } u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) unsigned int fds_size = sizeof(*fds) * fds_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct msghdr msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) .msg_iov = &iov,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) .msg_iovlen = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .msg_control = u.control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .msg_controllen = CMSG_SPACE(fds_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (fds_num > OS_SENDMSG_MAX_FDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) memset(u.control, 0, sizeof(u.control));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) cmsg->cmsg_level = SOL_SOCKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) cmsg->cmsg_type = SCM_RIGHTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) cmsg->cmsg_len = CMSG_LEN(fds_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) memcpy(CMSG_DATA(cmsg), fds, fds_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) err = sendmsg(fd, &msg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int os_poll(unsigned int n, const int *fds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /* currently need 2 FDs at most so avoid dynamic allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct pollfd pollfds[2] = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (n > ARRAY_SIZE(pollfds))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) pollfds[i].fd = fds[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) pollfds[i].events = POLLIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ret = poll(pollfds, n, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* Return the index of the available FD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (pollfds[i].revents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }