int fchmodat(int fd, const char *path, mode_t mode, int flag) { if (!flag) return syscall(SYS_fchmodat, fd, path, mode, flag); if (flag != AT_SYMLINK_NOFOLLOW) return __syscall_ret(-EINVAL); struct stat st; int ret, fd2; char proc[15+3*sizeof(int)]; if ((ret = __syscall(SYS_fstatat, fd, path, &st, flag))) return __syscall_ret(ret); if (S_ISLNK(st.st_mode)) return __syscall_ret(-EOPNOTSUPP); if ((fd2 = __syscall(SYS_openat, fd, path, O_RDONLY|O_PATH|O_NOFOLLOW|O_NOCTTY)) < 0) { if (fd2 == -ELOOP) return __syscall_ret(-EOPNOTSUPP); return __syscall_ret(fd2); } __procfdname(proc, fd2); if (!(ret = __syscall(SYS_stat, proc, &st)) && !S_ISLNK(st.st_mode)) ret = __syscall(SYS_chmod, proc, mode); __syscall(SYS_close, fd2); return __syscall_ret(ret); }
int fexecve(int fd, char *const argv[], char *const envp[]) { char buf[15 + 3*sizeof(int)]; __procfdname(buf, fd); execve(buf, argv, envp); if (errno == ENOENT) errno = EBADF; return -1; }
int fchdir(int fd) { int ret = __syscall(SYS_fchdir, fd); if (ret != -EBADF || fd < 0) return __syscall_ret(ret); char buf[15+3*sizeof(int)]; __procfdname(buf, fd); return syscall(SYS_chdir, buf); }
int fstat(int fd, struct stat *st) { int ret = __syscall(SYS_fstat, fd, mcfi_sandbox_mask(st)); if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) return __syscall_ret(ret); char buf[15+3*sizeof(int)]; __procfdname(buf, fd); return syscall(SYS_stat, buf, mcfi_sandbox_mask(st)); }
int fexecve(int fd, char *const argv[], char *const envp[]) { int r = __syscall(SYS_execveat, fd, "", argv, envp, AT_EMPTY_PATH); if (r != -ENOSYS) return __syscall_ret(r); char buf[15 + 3*sizeof(int)]; __procfdname(buf, fd); execve(buf, argv, envp); if (errno == ENOENT) errno = EBADF; return -1; }
int fstat(int fd, struct stat* st) { int ret = __syscall(SYS_fstat, fd, st); if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) return __syscall_ret(ret); char buf[15 + 3 * sizeof(int)]; __procfdname(buf, fd); #ifdef SYS_stat return syscall(SYS_stat, buf, st); #else return syscall(SYS_fstatat, AT_FDCWD, buf, st, 0); #endif }
int ttyname_r(int fd, char *name, size_t size) { char procname[sizeof "/proc/self/fd/" + 3*sizeof(int) + 2]; ssize_t l; if (!isatty(fd)) return ENOTTY; __procfdname(procname, fd); l = readlink(procname, name, size); if (l < 0) return errno; else if (l == size) return ERANGE; else { name[l] = 0; return 0; } }
int ttyname_r(int fd, char *name, size_t size) { struct stat st1, st2; char procname[sizeof "/proc/self/fd/" + 3*sizeof(int) + 2]; ssize_t l; if (!isatty(fd)) return errno; __procfdname(procname, fd); l = readlink(procname, name, size); if (l < 0) return errno; else if (l == size) return ERANGE; name[l] = 0; if (stat(name, &st1) || fstat(fd, &st2)) return errno; if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) return ENODEV; return 0; }