diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master index f00100e48f9a..1658b4ee1561 100644 --- a/sys/amd64/linux32/syscalls.master +++ b/sys/amd64/linux32/syscalls.master @@ -1,504 +1,504 @@ $FreeBSD$ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 ; System call name/number master file (or rather, slave, from LINUX). ; Processed to create linux_sysent.c, linux_proto.h and linux_syscall.h. ; Columns: number audit type nargs name alt{name,tag,rtyp}/comments ; number system call number, must be in order ; audit the audit event associated with the system call ; A value of AUE_NULL means no auditing, but it also means that ; there is no audit event for the call at this time. For the ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, OBSOL, UNIMPL ; name psuedo-prototype of syscall routine ; If one of the following alts is different, then all appear: ; altname name of system call if different ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL/OBSOL, name continues with comments ; types: ; STD always included ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only #include "opt_compat.h" #include #include #include #include #include #include ; Isn't pretty, but there seems to be no other way to trap nosys #define nosys linux_nosys ; #ifdef's, etc. may be included, and are copied to the output files. 0 AUE_NULL UNIMPL setup 1 AUE_EXIT NOPROTO { void sys_exit(int rval); } exit \ sys_exit_args void 2 AUE_FORK STD { int linux_fork(void); } 3 AUE_NULL NOPROTO { int read(int fd, char *buf, \ u_int nbyte); } 4 AUE_NULL NOPROTO { int write(int fd, char *buf, \ u_int nbyte); } 5 AUE_OPEN_RWTC STD { int linux_open(char *path, l_int flags, \ l_int mode); } 6 AUE_CLOSE NOPROTO { int close(int fd); } 7 AUE_WAIT4 STD { int linux_waitpid(l_pid_t pid, \ l_int *status, l_int options); } 8 AUE_CREAT STD { int linux_creat(char *path, \ l_int mode); } 9 AUE_LINK STD { int linux_link(char *path, char *to); } 10 AUE_UNLINK STD { int linux_unlink(char *path); } 11 AUE_EXECVE STD { int linux_execve(char *path, u_int32_t *argp, \ u_int32_t *envp); } 12 AUE_CHDIR STD { int linux_chdir(char *path); } 13 AUE_NULL STD { int linux_time(l_time_t *tm); } 14 AUE_MKNOD STD { int linux_mknod(char *path, l_int mode, \ l_dev_t dev); } 15 AUE_CHMOD STD { int linux_chmod(char *path, \ l_mode_t mode); } 16 AUE_LCHOWN STD { int linux_lchown16(char *path, \ l_uid16_t uid, l_gid16_t gid); } 17 AUE_NULL UNIMPL break 18 AUE_STAT STD { int linux_stat(char *path, \ struct linux_stat *up); } 19 AUE_LSEEK STD { int linux_lseek(l_uint fdes, l_off_t off, \ l_int whence); } 20 AUE_GETPID STD { int linux_getpid(void); } 21 AUE_MOUNT STD { int linux_mount(char *specialfile, \ char *dir, char *filesystemtype, \ l_ulong rwflag, void *data); } 22 AUE_UMOUNT STD { int linux_oldumount(char *path); } 23 AUE_SETUID STD { int linux_setuid16(l_uid16_t uid); } 24 AUE_GETUID STD { int linux_getuid16(void); } 25 AUE_SETTIMEOFDAY STD { int linux_stime(void); } 26 AUE_PTRACE STD { int linux_ptrace(l_long req, l_long pid, \ l_long addr, l_long data); } 27 AUE_NULL STD { int linux_alarm(l_uint secs); } 28 AUE_FSTAT UNIMPL fstat 29 AUE_NULL STD { int linux_pause(void); } 30 AUE_UTIME STD { int linux_utime(char *fname, \ struct l_utimbuf *times); } 31 AUE_NULL UNIMPL stty 32 AUE_NULL UNIMPL gtty -33 AUE_ACCESS STD { int linux_access(char *path, l_int flags); } +33 AUE_ACCESS STD { int linux_access(char *path, l_int amode); } 34 AUE_NICE STD { int linux_nice(l_int inc); } 35 AUE_NULL UNIMPL ftime 36 AUE_SYNC NOPROTO { int sync(void); } 37 AUE_KILL STD { int linux_kill(l_int pid, l_int signum); } 38 AUE_RENAME STD { int linux_rename(char *from, char *to); } 39 AUE_MKDIR STD { int linux_mkdir(char *path, l_int mode); } 40 AUE_RMDIR STD { int linux_rmdir(char *path); } 41 AUE_DUP NOPROTO { int dup(u_int fd); } 42 AUE_PIPE STD { int linux_pipe(l_ulong *pipefds); } 43 AUE_NULL STD { int linux_times(struct l_times_argv *buf); } 44 AUE_NULL UNIMPL prof 45 AUE_NULL STD { int linux_brk(l_ulong dsend); } 46 AUE_SETGID STD { int linux_setgid16(l_gid16_t gid); } 47 AUE_GETGID STD { int linux_getgid16(void); } 48 AUE_NULL STD { int linux_signal(l_int sig, \ l_handler_t handler); } 49 AUE_GETEUID STD { int linux_geteuid16(void); } 50 AUE_GETEGID STD { int linux_getegid16(void); } 51 AUE_ACCT NOPROTO { int acct(char *path); } 52 AUE_UMOUNT STD { int linux_umount(char *path, l_int flags); } 53 AUE_NULL UNIMPL lock 54 AUE_IOCTL STD { int linux_ioctl(l_uint fd, l_uint cmd, \ uintptr_t arg); } 55 AUE_FCNTL STD { int linux_fcntl(l_uint fd, l_uint cmd, \ uintptr_t arg); } 56 AUE_NULL UNIMPL mpx 57 AUE_SETPGRP NOPROTO { int setpgid(int pid, int pgid); } 58 AUE_NULL UNIMPL ulimit 59 AUE_NULL STD { int linux_olduname(void); } 60 AUE_UMASK NOPROTO { int umask(int newmask); } 61 AUE_CHROOT NOPROTO { int chroot(char *path); } 62 AUE_NULL STD { int linux_ustat(l_dev_t dev, \ struct l_ustat *ubuf); } 63 AUE_DUP2 NOPROTO { int dup2(u_int from, u_int to); } 64 AUE_GETPPID STD { int linux_getppid(void); } 65 AUE_GETPGRP NOPROTO { int getpgrp(void); } 66 AUE_SETSID NOPROTO { int setsid(void); } 67 AUE_NULL STD { int linux_sigaction(l_int sig, \ l_osigaction_t *nsa, \ l_osigaction_t *osa); } 68 AUE_NULL STD { int linux_sgetmask(void); } 69 AUE_NULL STD { int linux_ssetmask(l_osigset_t mask); } 70 AUE_SETREUID STD { int linux_setreuid16(l_uid16_t ruid, \ l_uid16_t euid); } 71 AUE_SETREGID STD { int linux_setregid16(l_gid16_t rgid, \ l_gid16_t egid); } 72 AUE_NULL STD { int linux_sigsuspend(l_int hist0, \ l_int hist1, l_osigset_t mask); } 73 AUE_NULL STD { int linux_sigpending(l_osigset_t *mask); } 74 AUE_SYSCTL STD { int linux_sethostname(char *hostname, \ u_int len); } 75 AUE_SETRLIMIT STD { int linux_setrlimit(l_uint resource, \ struct l_rlimit *rlim); } 76 AUE_GETRLIMIT STD { int linux_old_getrlimit(l_uint resource, \ struct l_rlimit *rlim); } 77 AUE_GETRUSAGE STD { int linux_getrusage(int who, \ struct l_rusage *rusage); } 78 AUE_NULL STD { int linux_gettimeofday( \ struct l_timeval *tp, \ struct timezone *tzp); } 79 AUE_SETTIMEOFDAY STD { int linux_settimeofday( \ struct l_timeval *tp, \ struct timezone *tzp); } 80 AUE_GETGROUPS STD { int linux_getgroups16(l_uint gidsetsize, \ l_gid16_t *gidset); } 81 AUE_SETGROUPS STD { int linux_setgroups16(l_uint gidsetsize, \ l_gid16_t *gidset); } 82 AUE_SELECT STD { int linux_old_select( \ struct l_old_select_argv *ptr); } 83 AUE_SYMLINK STD { int linux_symlink(char *path, char *to); } 84 AUE_LSTAT STD { int linux_lstat(char *path, struct linux_lstat *up); } 85 AUE_READLINK STD { int linux_readlink(char *name, char *buf, \ l_int count); } 86 AUE_USELIB UNIMPL linux_uselib 87 AUE_SWAPON NOPROTO { int swapon(char *name); } 88 AUE_REBOOT STD { int linux_reboot(l_int magic1, \ l_int magic2, l_uint cmd, void *arg); } 89 AUE_GETDIRENTRIES STD { int linux_readdir(l_uint fd, \ struct l_dirent *dent, l_uint count); } 90 AUE_MMAP STD { int linux_mmap(struct l_mmap_argv *ptr); } 91 AUE_MUNMAP NOPROTO { int munmap(caddr_t addr, int len); } 92 AUE_TRUNCATE STD { int linux_truncate(char *path, \ l_ulong length); } 93 AUE_FTRUNCATE STD { int linux_ftruncate(int fd, long length); } 94 AUE_FCHMOD NOPROTO { int fchmod(int fd, int mode); } 95 AUE_FCHOWN NOPROTO { int fchown(int fd, int uid, int gid); } 96 AUE_GETPRIORITY STD { int linux_getpriority(int which, int who); } 97 AUE_SETPRIORITY NOPROTO { int setpriority(int which, int who, \ int prio); } 98 AUE_PROFILE UNIMPL profil 99 AUE_STATFS STD { int linux_statfs(char *path, \ struct l_statfs_buf *buf); } 100 AUE_FSTATFS STD { int linux_fstatfs(l_uint fd, \ struct l_statfs_buf *buf); } 101 AUE_NULL UNIMPL ioperm 102 AUE_NULL STD { int linux_socketcall(l_int what, \ l_ulong args); } 103 AUE_NULL STD { int linux_syslog(l_int type, char *buf, \ l_int len); } 104 AUE_SETITIMER STD { int linux_setitimer(l_int which, \ struct l_itimerval *itv, \ struct l_itimerval *oitv); } 105 AUE_GETITIMER STD { int linux_getitimer(l_int which, \ struct l_itimerval *itv); } 106 AUE_STAT STD { int linux_newstat(char *path, \ struct l_newstat *buf); } 107 AUE_LSTAT STD { int linux_newlstat(char *path, \ struct l_newstat *buf); } 108 AUE_FSTAT STD { int linux_newfstat(l_uint fd, \ struct l_newstat *buf); } 109 AUE_NULL STD { int linux_uname(void); } 110 AUE_NULL STD { int linux_iopl(l_ulong level); } 111 AUE_NULL STD { int linux_vhangup(void); } 112 AUE_NULL UNIMPL idle 113 AUE_NULL UNIMPL vm86old 114 AUE_WAIT4 STD { int linux_wait4(l_pid_t pid, \ l_uint *status, l_int options, \ struct l_rusage *rusage); } 115 AUE_SWAPOFF STD { int linux_swapoff(void); } 116 AUE_NULL STD { int linux_sysinfo(struct l_sysinfo *info); } 117 AUE_NULL STD { int linux_ipc(l_uint what, l_int arg1, \ l_int arg2, l_int arg3, void *ptr, \ l_long arg5); } 118 AUE_FSYNC NOPROTO { int fsync(int fd); } 119 AUE_SIGRETURN STD { int linux_sigreturn( \ struct l_sigframe *sfp); } 120 AUE_RFORK STD { int linux_clone(l_int flags, void *stack, \ void *parent_tidptr, void *tls, void * child_tidptr); } 121 AUE_SYSCTL STD { int linux_setdomainname(char *name, \ int len); } 122 AUE_NULL STD { int linux_newuname( \ struct l_new_utsname *buf); } 123 AUE_NULL UNIMPL modify_ldt 124 AUE_ADJTIME STD { int linux_adjtimex(void); } 125 AUE_MPROTECT STD { int linux_mprotect(caddr_t addr, int len, \ int prot); } 126 AUE_SIGPROCMASK STD { int linux_sigprocmask(l_int how, \ l_osigset_t *mask, l_osigset_t *omask); } 127 AUE_NULL STD { int linux_create_module(void); } 128 AUE_NULL STD { int linux_init_module(void); } 129 AUE_NULL STD { int linux_delete_module(void); } 130 AUE_NULL STD { int linux_get_kernel_syms(void); } 131 AUE_QUOTACTL STD { int linux_quotactl(void); } 132 AUE_GETPGID NOPROTO { int getpgid(int pid); } 133 AUE_FCHDIR NOPROTO { int fchdir(int fd); } 134 AUE_BDFLUSH STD { int linux_bdflush(void); } 135 AUE_NULL STD { int linux_sysfs(l_int option, \ l_ulong arg1, l_ulong arg2); } 136 AUE_PERSONALITY STD { int linux_personality(l_ulong per); } 137 AUE_NULL UNIMPL afs_syscall 138 AUE_SETFSUID STD { int linux_setfsuid16(l_uid16_t uid); } 139 AUE_SETFSGID STD { int linux_setfsgid16(l_gid16_t gid); } 140 AUE_LSEEK STD { int linux_llseek(l_int fd, l_ulong ohigh, \ l_ulong olow, l_loff_t *res, \ l_uint whence); } 141 AUE_GETDIRENTRIES STD { int linux_getdents(l_uint fd, void *dent, \ l_uint count); } 142 AUE_SELECT STD { int linux_select(l_int nfds, \ l_fd_set *readfds, l_fd_set *writefds, \ l_fd_set *exceptfds, \ struct l_timeval *timeout); } 143 AUE_FLOCK NOPROTO { int flock(int fd, int how); } 144 AUE_MSYNC STD { int linux_msync(l_ulong addr, \ l_size_t len, l_int fl); } 145 AUE_READV STD { int linux_readv(l_ulong fd, struct l_iovec32 *iovp, \ l_ulong iovcnt); } 146 AUE_WRITEV STD { int linux_writev(l_ulong fd, struct l_iovec32 *iovp, \ l_ulong iovcnt); } 147 AUE_GETSID STD { int linux_getsid(l_pid_t pid); } 148 AUE_NULL STD { int linux_fdatasync(l_uint fd); } 149 AUE_SYSCTL STD { int linux_sysctl( \ struct l___sysctl_args *args); } 150 AUE_MLOCK NOPROTO { int mlock(const void *addr, size_t len); } 151 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, size_t len); } 152 AUE_MLOCKALL NOPROTO { int mlockall(int how); } 153 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } 154 AUE_SCHED_SETPARAM NOPROTO { int sched_setparam(pid_t pid, \ const struct sched_param *param); } 155 AUE_SCHED_GETPARAM NOPROTO { int sched_getparam(pid_t pid, \ struct sched_param *param); } 156 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( \ l_pid_t pid, l_int policy, \ struct l_sched_param *param); } 157 AUE_SCHED_GETSCHEDULER STD { int linux_sched_getscheduler( \ l_pid_t pid); } 158 AUE_NULL NOPROTO { int sched_yield(void); } 159 AUE_SCHED_GET_PRIORITY_MAX STD { int linux_sched_get_priority_max( \ l_int policy); } 160 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( \ l_int policy); } 161 AUE_SCHED_RR_GET_INTERVAL STD { int linux_sched_rr_get_interval(l_pid_t pid, \ struct l_timespec *interval); } 162 AUE_NULL STD { int linux_nanosleep( \ const struct l_timespec *rqtp, \ struct l_timespec *rmtp); } 163 AUE_NULL STD { int linux_mremap(l_ulong addr, \ l_ulong old_len, l_ulong new_len, \ l_ulong flags, l_ulong new_addr); } 164 AUE_SETRESUID STD { int linux_setresuid16(l_uid16_t ruid, \ l_uid16_t euid, l_uid16_t suid); } 165 AUE_GETRESUID STD { int linux_getresuid16(l_uid16_t *ruid, \ l_uid16_t *euid, l_uid16_t *suid); } 166 AUE_NULL UNIMPL vm86 167 AUE_NULL STD { int linux_query_module(void); } 168 AUE_POLL NOPROTO { int poll(struct pollfd *fds, \ unsigned int nfds, int timeout); } 169 AUE_NULL STD { int linux_nfsservctl(void); } 170 AUE_SETRESGID STD { int linux_setresgid16(l_gid16_t rgid, \ l_gid16_t egid, l_gid16_t sgid); } 171 AUE_GETRESGID STD { int linux_getresgid16(l_gid16_t *rgid, \ l_gid16_t *egid, l_gid16_t *sgid); } 172 AUE_PRCTL STD { int linux_prctl(l_int option, l_int arg2, l_int arg3, \ l_int arg4, l_int arg5); } 173 AUE_NULL STD { int linux_rt_sigreturn( \ struct l_ucontext *ucp); } 174 AUE_NULL STD { int linux_rt_sigaction(l_int sig, \ l_sigaction_t *act, l_sigaction_t *oact, \ l_size_t sigsetsize); } 175 AUE_NULL STD { int linux_rt_sigprocmask(l_int how, \ l_sigset_t *mask, l_sigset_t *omask, \ l_size_t sigsetsize); } 176 AUE_NULL STD { int linux_rt_sigpending(l_sigset_t *set, \ l_size_t sigsetsize); } 177 AUE_NULL STD { int linux_rt_sigtimedwait(l_sigset_t *mask, \ l_siginfo_t *ptr, \ struct l_timeval *timeout, \ l_size_t sigsetsize); } 178 AUE_NULL STD { int linux_rt_sigqueueinfo(void); } 179 AUE_NULL STD { int linux_rt_sigsuspend( \ l_sigset_t *newset, \ l_size_t sigsetsize); } 180 AUE_PREAD STD { int linux_pread(l_uint fd, char *buf, \ l_size_t nbyte, l_loff_t offset); } 181 AUE_PWRITE STD { int linux_pwrite(l_uint fd, char *buf, \ l_size_t nbyte, l_loff_t offset); } 182 AUE_CHOWN STD { int linux_chown16(char *path, \ l_uid16_t uid, l_gid16_t gid); } 183 AUE_GETCWD STD { int linux_getcwd(char *buf, \ l_ulong bufsize); } 184 AUE_CAPGET STD { int linux_capget(struct l_user_cap_header *hdrp, \ struct l_user_cap_data *datap); } 185 AUE_CAPSET STD { int linux_capset(struct l_user_cap_header *hdrp, \ struct l_user_cap_data *datap); } 186 AUE_NULL STD { int linux_sigaltstack(l_stack_t *uss, \ l_stack_t *uoss); } 187 AUE_SENDFILE STD { int linux_sendfile(void); } 188 AUE_GETPMSG UNIMPL getpmsg 189 AUE_PUTPMSG UNIMPL putpmsg 190 AUE_VFORK STD { int linux_vfork(void); } 191 AUE_GETRLIMIT STD { int linux_getrlimit(l_uint resource, \ struct l_rlimit *rlim); } 192 AUE_MMAP STD { int linux_mmap2(l_ulong addr, l_ulong len, \ l_ulong prot, l_ulong flags, l_ulong fd, \ l_ulong pgoff); } 193 AUE_TRUNCATE STD { int linux_truncate64(char *path, \ l_loff_t length); } 194 AUE_FTRUNCATE STD { int linux_ftruncate64(l_uint fd, \ l_loff_t length); } 195 AUE_STAT STD { int linux_stat64(char *filename, \ struct l_stat64 *statbuf, l_long flags); } 196 AUE_LSTAT STD { int linux_lstat64(char *filename, \ struct l_stat64 *statbuf, l_long flags); } 197 AUE_FSTAT STD { int linux_fstat64(l_ulong fd, \ struct l_stat64 *statbuf, l_long flags); } 198 AUE_LCHOWN STD { int linux_lchown(char *path, l_uid_t uid, \ l_gid_t gid); } 199 AUE_GETUID STD { int linux_getuid(void); } 200 AUE_GETGID STD { int linux_getgid(void); } 201 AUE_GETEUID NOPROTO { int geteuid(void); } 202 AUE_GETEGID NOPROTO { int getegid(void); } 203 AUE_SETREUID NOPROTO { int setreuid(uid_t ruid, uid_t euid); } 204 AUE_SETREGID NOPROTO { int setregid(gid_t rgid, gid_t egid); } 205 AUE_GETGROUPS STD { int linux_getgroups(l_int gidsetsize, \ l_gid_t *grouplist); } 206 AUE_SETGROUPS STD { int linux_setgroups(l_int gidsetsize, \ l_gid_t *grouplist); } 207 AUE_FCHOWN NODEF fchown fchown fchown_args int 208 AUE_SETRESUID NOPROTO { int setresuid(uid_t ruid, uid_t euid, \ uid_t suid); } 209 AUE_GETRESUID NOPROTO { int getresuid(uid_t *ruid, uid_t *euid, \ uid_t *suid); } 210 AUE_SETRESGID NOPROTO { int setresgid(gid_t rgid, gid_t egid, \ gid_t sgid); } 211 AUE_GETRESGID NOPROTO { int getresgid(gid_t *rgid, gid_t *egid, \ gid_t *sgid); } 212 AUE_CHOWN STD { int linux_chown(char *path, l_uid_t uid, \ l_gid_t gid); } 213 AUE_SETUID NOPROTO { int setuid(uid_t uid); } 214 AUE_SETGID NOPROTO { int setgid(gid_t gid); } 215 AUE_SETFSUID STD { int linux_setfsuid(l_uid_t uid); } 216 AUE_SETFSGID STD { int linux_setfsgid(l_gid_t gid); } 217 AUE_PIVOT_ROOT STD { int linux_pivot_root(char *new_root, \ char *put_old); } 218 AUE_MINCORE STD { int linux_mincore(l_ulong start, \ l_size_t len, u_char *vec); } 219 AUE_MADVISE NOPROTO { int madvise(void *addr, size_t len, \ int behav); } 220 AUE_GETDIRENTRIES STD { int linux_getdents64(l_uint fd, \ void *dirent, l_uint count); } 221 AUE_FCNTL STD { int linux_fcntl64(l_uint fd, l_uint cmd, \ uintptr_t arg); } 222 AUE_NULL UNIMPL 223 AUE_NULL UNIMPL 224 AUE_NULL STD { long linux_gettid(void); } 225 AUE_NULL UNIMPL linux_readahead 226 AUE_NULL STD { int linux_setxattr(void); } 227 AUE_NULL STD { int linux_lsetxattr(void); } 228 AUE_NULL STD { int linux_fsetxattr(void); } 229 AUE_NULL STD { int linux_getxattr(void); } 230 AUE_NULL STD { int linux_lgetxattr(void); } 231 AUE_NULL STD { int linux_fgetxattr(void); } 232 AUE_NULL STD { int linux_listxattr(void); } 233 AUE_NULL STD { int linux_llistxattr(void); } 234 AUE_NULL STD { int linux_flistxattr(void); } 235 AUE_NULL STD { int linux_removexattr(void); } 236 AUE_NULL STD { int linux_lremovexattr(void); } 237 AUE_NULL STD { int linux_fremovexattr(void); } 238 AUE_NULL STD { int linux_tkill(int tid, int sig); } 239 AUE_SENDFILE UNIMPL linux_sendfile64 240 AUE_NULL STD { int linux_sys_futex(void *uaddr, int op, uint32_t val, \ struct l_timespec *timeout, uint32_t *uaddr2, uint32_t val3); } 241 AUE_NULL STD { int linux_sched_setaffinity(l_pid_t pid, l_uint len, \ l_ulong *user_mask_ptr); } 242 AUE_NULL STD { int linux_sched_getaffinity(l_pid_t pid, l_uint len, \ l_ulong *user_mask_ptr); } 243 AUE_NULL STD { int linux_set_thread_area(struct l_user_desc *desc); } 244 AUE_NULL UNIMPL linux_get_thread_area 245 AUE_NULL UNIMPL linux_io_setup 246 AUE_NULL UNIMPL linux_io_destroy 247 AUE_NULL UNIMPL linux_io_getevents 248 AUE_NULL UNIMPL linux_io_submit 249 AUE_NULL UNIMPL linux_io_cancel 250 AUE_NULL STD { int linux_fadvise64(void); } 251 AUE_NULL UNIMPL 252 AUE_EXIT STD { int linux_exit_group(int error_code); } 253 AUE_NULL STD { int linux_lookup_dcookie(void); } 254 AUE_NULL STD { int linux_epoll_create(void); } 255 AUE_NULL STD { int linux_epoll_ctl(void); } 256 AUE_NULL STD { int linux_epoll_wait(void); } 257 AUE_NULL STD { int linux_remap_file_pages(void); } 258 AUE_NULL STD { int linux_set_tid_address(int *tidptr); } 259 AUE_NULL STD { int linux_timer_create(void); } 260 AUE_NULL STD { int linux_timer_settime(void); } 261 AUE_NULL STD { int linux_timer_gettime(void); } 262 AUE_NULL STD { int linux_timer_getoverrun(void); } 263 AUE_NULL STD { int linux_timer_delete(void); } 264 AUE_CLOCK_SETTIME STD { int linux_clock_settime(clockid_t which, struct l_timespec *tp); } 265 AUE_NULL STD { int linux_clock_gettime(clockid_t which, struct l_timespec *tp); } 266 AUE_NULL STD { int linux_clock_getres(clockid_t which, struct l_timespec *tp); } 267 AUE_NULL STD { int linux_clock_nanosleep(clockid_t which, int flags, \ struct l_timespec *rqtp, struct l_timespec *rmtp); } 268 AUE_STATFS STD { int linux_statfs64(char *path, size_t bufsize, struct l_statfs64_buf *buf); } 269 AUE_FSTATFS STD { int linux_fstatfs64(void); } 270 AUE_NULL STD { int linux_tgkill(int tgid, int pid, int sig); } 271 AUE_UTIMES STD { int linux_utimes(char *fname, \ struct l_timeval *tptr); } 272 AUE_NULL STD { int linux_fadvise64_64(void); } 273 AUE_NULL UNIMPL 274 AUE_NULL STD { int linux_mbind(void); } 275 AUE_NULL STD { int linux_get_mempolicy(void); } 276 AUE_NULL STD { int linux_set_mempolicy(void); } 277 AUE_NULL STD { int linux_mq_open(void); } 278 AUE_NULL STD { int linux_mq_unlink(void); } 279 AUE_NULL STD { int linux_mq_timedsend(void); } 280 AUE_NULL STD { int linux_mq_timedreceive(void); } 281 AUE_NULL STD { int linux_mq_notify(void); } 282 AUE_NULL STD { int linux_mq_getsetattr(void); } 283 AUE_NULL STD { int linux_kexec_load(void); } 284 AUE_NULL STD { int linux_waitid(void); } 285 AUE_NULL UNIMPL 286 AUE_NULL STD { int linux_add_key(void); } 287 AUE_NULL STD { int linux_request_key(void); } 288 AUE_NULL STD { int linux_keyctl(void); } 289 AUE_NULL STD { int linux_ioprio_set(void); } 290 AUE_NULL STD { int linux_ioprio_get(void); } 291 AUE_NULL STD { int linux_inotify_init(void); } 292 AUE_NULL STD { int linux_inotify_add_watch(void); } 293 AUE_NULL STD { int linux_inotify_rm_watch(void); } 294 AUE_NULL STD { int linux_migrate_pages(void); } 295 AUE_OPEN_RWTC STD { int linux_openat(l_int dfd, const char *filename, \ l_int flags, l_int mode); } 296 AUE_MKDIRAT STD { int linux_mkdirat(l_int dfd, const char *pathname, \ l_int mode); } 297 AUE_MKNODAT STD { int linux_mknodat(l_int dfd, const char *filename, \ l_int mode, l_uint dev); } 298 AUE_FCHOWNAT STD { int linux_fchownat(l_int dfd, const char *filename, \ l_uid16_t uid, l_gid16_t gid, l_int flag); } 299 AUE_FUTIMESAT STD { int linux_futimesat(l_int dfd, char *filename, \ struct l_timeval *utimes); } 300 AUE_FSTATAT STD { int linux_fstatat64(l_int dfd, char *pathname, \ struct l_stat64 *statbuf, l_int flag); } 301 AUE_UNLINKAT STD { int linux_unlinkat(l_int dfd, const char *pathname, \ l_int flag); } 302 AUE_RENAMEAT STD { int linux_renameat(l_int olddfd, const char *oldname, \ l_int newdfd, const char *newname); } 303 AUE_LINKAT STD { int linux_linkat(l_int olddfd, const char *oldname, \ l_int newdfd, const char *newname, l_int flags); } 304 AUE_SYMLINKAT STD { int linux_symlinkat(const char *oldname, l_int newdfd, \ const char *newname); } 305 AUE_READLINKAT STD { int linux_readlinkat(l_int dfd, const char *path, \ char *buf, l_int bufsiz); } 306 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \ l_mode_t mode); } -307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int mode); } +307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode); } 308 AUE_NULL STD { int linux_pselect6(void); } 309 AUE_NULL STD { int linux_ppoll(void); } 310 AUE_NULL STD { int linux_unshare(void); } 311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ l_size_t len); } 312 AUE_NULL STD { int linux_get_robust_list(l_int pid, struct linux_robust_list_head *head, \ l_size_t *len); } 313 AUE_NULL STD { int linux_splice(void); } 314 AUE_NULL STD { int linux_sync_file_range(void); } 315 AUE_NULL STD { int linux_tee(void); } 316 AUE_NULL STD { int linux_vmsplice(void); } diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index cb22f8b092f9..78598c3a55ee 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -1,997 +1,997 @@ $FreeBSD$ ; from: @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; from: src/sys/kern/syscalls.master 1.107 ; ; System call name/number master file. ; Processed to created init_sysent.c, syscalls.c and syscall.h. ; Columns: number audit type name alt{name,tag,rtyp}/comments ; number system call number, must be in order ; audit the audit event associated with the system call ; A value of AUE_NULL means no auditing, but it also means that ; there is no audit event for the call at this time. For the ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, OBSOL, UNIMPL, COMPAT, COMPAT4, COMPAT6, ; COMPAT7, NODEF, NOARGS, NOPROTO, NOSTD ; The COMPAT* options may be combined with one or more NO* ; options separated by '|' with no spaces (e.g. COMPAT|NOARGS) ; name psuedo-prototype of syscall routine ; If one of the following alts is different, then all appear: ; altname name of system call if different ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL/OBSOL, name continues with comments ; types: ; STD always included ; COMPAT included on COMPAT #ifdef ; COMPAT4 included on COMPAT4 #ifdef (FreeBSD 4 compat) ; COMPAT6 included on COMPAT6 #ifdef (FreeBSD 6 compat) ; COMPAT7 included on COMPAT7 #ifdef (FreeBSD 7 compat) ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only ; NOSTD implemented but as a lkm that can be statically ; compiled in; sysent entry will be filled with lkmressys ; so the SYSCALL_MODULE macro works ; NOARGS same as STD except do not create structure in sys/sysproto.h ; NODEF same as STD except only have the entry in the syscall table ; added. Meaning - do not create structure or function ; prototype in sys/sysproto.h ; NOPROTO same as STD except do not create structure or ; function prototype in sys/sysproto.h. Does add a ; definition to syscall.h besides adding a sysent. ; #ifdef's, etc. may be included, and are copied to the output files. #include #include #include #include #include #include #include #if !defined(PAD64_REQUIRED) && defined(__powerpc__) #define PAD64_REQUIRED #endif ; Reserved/unimplemented system calls in the range 0-150 inclusive ; are reserved for use in future Berkeley releases. ; Additional system calls implemented in vendor and other ; redistributions should be placed in the reserved range at the end ; of the current calls. 0 AUE_NULL NOPROTO { int nosys(void); } syscall nosys_args int 1 AUE_EXIT NOPROTO { void sys_exit(int rval); } exit \ sys_exit_args void 2 AUE_FORK NOPROTO { int fork(void); } 3 AUE_READ NOPROTO { ssize_t read(int fd, void *buf, \ size_t nbyte); } 4 AUE_WRITE NOPROTO { ssize_t write(int fd, const void *buf, \ size_t nbyte); } 5 AUE_OPEN_RWTC NOPROTO { int open(char *path, int flags, \ int mode); } 6 AUE_CLOSE NOPROTO { int close(int fd); } 7 AUE_WAIT4 STD { int freebsd32_wait4(int pid, int *status, \ int options, struct rusage32 *rusage); } 8 AUE_CREAT OBSOL old creat 9 AUE_LINK NOPROTO { int link(char *path, char *link); } 10 AUE_UNLINK NOPROTO { int unlink(char *path); } 11 AUE_NULL OBSOL execv 12 AUE_CHDIR NOPROTO { int chdir(char *path); } 13 AUE_FCHDIR NOPROTO { int fchdir(int fd); } 14 AUE_MKNOD NOPROTO { int mknod(char *path, int mode, int dev); } 15 AUE_CHMOD NOPROTO { int chmod(char *path, int mode); } 16 AUE_CHOWN NOPROTO { int chown(char *path, int uid, int gid); } 17 AUE_NULL NOPROTO { int obreak(char *nsize); } break \ obreak_args int 18 AUE_GETFSSTAT COMPAT4 { int freebsd32_getfsstat( \ struct statfs32 *buf, long bufsize, \ int flags); } 19 AUE_LSEEK COMPAT { int freebsd32_lseek(int fd, int offset, \ int whence); } 20 AUE_GETPID NOPROTO { pid_t getpid(void); } 21 AUE_MOUNT NOPROTO { int mount(char *type, char *path, \ int flags, caddr_t data); } 22 AUE_UMOUNT NOPROTO { int unmount(char *path, int flags); } 23 AUE_SETUID NOPROTO { int setuid(uid_t uid); } 24 AUE_GETUID NOPROTO { uid_t getuid(void); } 25 AUE_GETEUID NOPROTO { uid_t geteuid(void); } 26 AUE_PTRACE NOPROTO { int ptrace(int req, pid_t pid, \ caddr_t addr, int data); } 27 AUE_RECVMSG STD { int freebsd32_recvmsg(int s, struct msghdr32 *msg, \ int flags); } 28 AUE_SENDMSG STD { int freebsd32_sendmsg(int s, struct msghdr32 *msg, \ int flags); } 29 AUE_RECVFROM STD { int freebsd32_recvfrom(int s, u_int32_t buf, \ u_int32_t len, int flags, u_int32_t from, \ u_int32_t fromlenaddr); } 30 AUE_ACCEPT NOPROTO { int accept(int s, caddr_t name, \ int *anamelen); } 31 AUE_GETPEERNAME NOPROTO { int getpeername(int fdes, caddr_t asa, \ int *alen); } 32 AUE_GETSOCKNAME NOPROTO { int getsockname(int fdes, caddr_t asa, \ int *alen); } -33 AUE_ACCESS NOPROTO { int access(char *path, int flags); } +33 AUE_ACCESS NOPROTO { int access(char *path, int amode); } 34 AUE_CHFLAGS NOPROTO { int chflags(char *path, int flags); } 35 AUE_FCHFLAGS NOPROTO { int fchflags(int fd, int flags); } 36 AUE_SYNC NOPROTO { int sync(void); } 37 AUE_KILL NOPROTO { int kill(int pid, int signum); } 38 AUE_STAT COMPAT { int freebsd32_stat(char *path, \ struct ostat32 *ub); } 39 AUE_GETPPID NOPROTO { pid_t getppid(void); } 40 AUE_LSTAT COMPAT { int freebsd32_lstat(char *path, \ struct ostat *ub); } 41 AUE_DUP NOPROTO { int dup(u_int fd); } 42 AUE_PIPE NOPROTO { int pipe(void); } 43 AUE_GETEGID NOPROTO { gid_t getegid(void); } 44 AUE_PROFILE NOPROTO { int profil(caddr_t samples, size_t size, \ size_t offset, u_int scale); } 45 AUE_KTRACE NOPROTO { int ktrace(const char *fname, int ops, \ int facs, int pid); } 46 AUE_SIGACTION COMPAT { int freebsd32_sigaction( int signum, \ struct osigaction32 *nsa, \ struct osigaction32 *osa); } 47 AUE_GETGID NOPROTO { gid_t getgid(void); } 48 AUE_SIGPROCMASK COMPAT { int freebsd32_sigprocmask(int how, \ osigset_t mask); } 49 AUE_GETLOGIN NOPROTO { int getlogin(char *namebuf, \ u_int namelen); } 50 AUE_SETLOGIN NOPROTO { int setlogin(char *namebuf); } 51 AUE_ACCT NOPROTO { int acct(char *path); } 52 AUE_SIGPENDING COMPAT { int freebsd32_sigpending(void); } 53 AUE_SIGALTSTACK STD { int freebsd32_sigaltstack( \ struct sigaltstack32 *ss, \ struct sigaltstack32 *oss); } 54 AUE_NULL STD { int freebsd32_ioctl(int fd, uint32_t com, \ struct md_ioctl32 *data); } 55 AUE_REBOOT NOPROTO { int reboot(int opt); } 56 AUE_REVOKE NOPROTO { int revoke(char *path); } 57 AUE_SYMLINK NOPROTO { int symlink(char *path, char *link); } 58 AUE_READLINK NOPROTO { ssize_t readlink(char *path, char *buf, \ size_t count); } 59 AUE_EXECVE STD { int freebsd32_execve(char *fname, \ u_int32_t *argv, u_int32_t *envv); } 60 AUE_UMASK NOPROTO { int umask(int newmask); } umask \ umask_args int 61 AUE_CHROOT NOPROTO { int chroot(char *path); } 62 AUE_FSTAT COMPAT { int freebsd32_fstat(int fd, \ struct ostat32 *ub); } 63 AUE_NULL OBSOL ogetkerninfo 64 AUE_NULL COMPAT { int freebsd32_getpagesize( \ int32_t dummy); } 65 AUE_MSYNC NOPROTO { int msync(void *addr, size_t len, \ int flags); } 66 AUE_VFORK NOPROTO { int vfork(void); } 67 AUE_NULL OBSOL vread 68 AUE_NULL OBSOL vwrite 69 AUE_SBRK NOPROTO { int sbrk(int incr); } 70 AUE_SSTK NOPROTO { int sstk(int incr); } 71 AUE_MMAP OBSOL ommap 72 AUE_O_VADVISE NOPROTO { int ovadvise(int anom); } vadvise \ ovadvise_args int 73 AUE_MUNMAP NOPROTO { int munmap(void *addr, size_t len); } 74 AUE_MPROTECT STD { int freebsd32_mprotect(const void *addr, \ size_t len, int prot); } 75 AUE_MADVISE NOPROTO { int madvise(void *addr, size_t len, \ int behav); } 76 AUE_NULL OBSOL vhangup 77 AUE_NULL OBSOL vlimit 78 AUE_MINCORE NOPROTO { int mincore(const void *addr, size_t len, \ char *vec); } 79 AUE_GETGROUPS NOPROTO { int getgroups(u_int gidsetsize, \ gid_t *gidset); } 80 AUE_SETGROUPS NOPROTO { int setgroups(u_int gidsetsize, \ gid_t *gidset); } 81 AUE_GETPGRP NOPROTO { int getpgrp(void); } 82 AUE_SETPGRP NOPROTO { int setpgid(int pid, int pgid); } 83 AUE_SETITIMER STD { int freebsd32_setitimer(u_int which, \ struct itimerval32 *itv, \ struct itimerval32 *oitv); } 84 AUE_NULL OBSOL owait ; XXX implement 85 AUE_SWAPON NOPROTO { int swapon(char *name); } 86 AUE_GETITIMER STD { int freebsd32_getitimer(u_int which, \ struct itimerval32 *itv); } 87 AUE_O_GETHOSTNAME OBSOL ogethostname 88 AUE_O_SETHOSTNAME OBSOL osethostname 89 AUE_GETDTABLESIZE NOPROTO { int getdtablesize(void); } 90 AUE_DUP2 NOPROTO { int dup2(u_int from, u_int to); } 91 AUE_NULL UNIMPL getdopt 92 AUE_FCNTL NOPROTO { int fcntl(int fd, int cmd, long arg); } 93 AUE_SELECT STD { int freebsd32_select(int nd, fd_set *in, \ fd_set *ou, fd_set *ex, \ struct timeval32 *tv); } 94 AUE_NULL UNIMPL setdopt 95 AUE_FSYNC NOPROTO { int fsync(int fd); } 96 AUE_SETPRIORITY NOPROTO { int setpriority(int which, int who, \ int prio); } 97 AUE_SOCKET NOPROTO { int socket(int domain, int type, \ int protocol); } 98 AUE_CONNECT NOPROTO { int connect(int s, caddr_t name, \ int namelen); } 99 AUE_NULL OBSOL oaccept 100 AUE_GETPRIORITY NOPROTO { int getpriority(int which, int who); } 101 AUE_NULL OBSOL osend 102 AUE_NULL OBSOL orecv 103 AUE_NULL COMPAT { int freebsd32_sigreturn( \ struct ia32_sigcontext3 *sigcntxp); } 104 AUE_BIND NOPROTO { int bind(int s, caddr_t name, \ int namelen); } 105 AUE_SETSOCKOPT NOPROTO { int setsockopt(int s, int level, \ int name, caddr_t val, int valsize); } 106 AUE_LISTEN NOPROTO { int listen(int s, int backlog); } 107 AUE_NULL OBSOL vtimes 108 AUE_O_SIGVEC COMPAT { int freebsd32_sigvec(int signum, \ struct sigvec32 *nsv, \ struct sigvec32 *osv); } 109 AUE_O_SIGBLOCK COMPAT { int freebsd32_sigblock(int mask); } 110 AUE_O_SIGSETMASK COMPAT { int freebsd32_sigsetmask( int mask); } 111 AUE_SIGSUSPEND COMPAT { int freebsd32_sigsuspend( int mask); } 112 AUE_O_SIGSTACK COMPAT { int freebsd32_sigstack( \ struct sigstack32 *nss, \ struct sigstack32 *oss); } 113 AUE_NULL OBSOL orecvmsg 114 AUE_NULL OBSOL osendmsg 115 AUE_NULL OBSOL vtrace 116 AUE_GETTIMEOFDAY STD { int freebsd32_gettimeofday( \ struct timeval32 *tp, \ struct timezone *tzp); } 117 AUE_GETRUSAGE STD { int freebsd32_getrusage(int who, \ struct rusage32 *rusage); } 118 AUE_GETSOCKOPT NOPROTO { int getsockopt(int s, int level, \ int name, caddr_t val, int *avalsize); } 119 AUE_NULL UNIMPL resuba (BSD/OS 2.x) 120 AUE_READV STD { int freebsd32_readv(int fd, \ struct iovec32 *iovp, u_int iovcnt); } 121 AUE_WRITEV STD { int freebsd32_writev(int fd, \ struct iovec32 *iovp, u_int iovcnt); } 122 AUE_SETTIMEOFDAY STD { int freebsd32_settimeofday( \ struct timeval32 *tv, \ struct timezone *tzp); } 123 AUE_FCHOWN NOPROTO { int fchown(int fd, int uid, int gid); } 124 AUE_FCHMOD NOPROTO { int fchmod(int fd, int mode); } 125 AUE_RECVFROM OBSOL orecvfrom 126 AUE_SETREUID NOPROTO { int setreuid(int ruid, int euid); } 127 AUE_SETREGID NOPROTO { int setregid(int rgid, int egid); } 128 AUE_RENAME NOPROTO { int rename(char *from, char *to); } 129 AUE_TRUNCATE OBSOL otruncate 130 AUE_FTRUNCATE OBSOL ftruncate 131 AUE_FLOCK NOPROTO { int flock(int fd, int how); } 132 AUE_MKFIFO NOPROTO { int mkfifo(char *path, int mode); } 133 AUE_SENDTO NOPROTO { int sendto(int s, caddr_t buf, \ size_t len, int flags, caddr_t to, \ int tolen); } 134 AUE_SHUTDOWN NOPROTO { int shutdown(int s, int how); } 135 AUE_SOCKETPAIR NOPROTO { int socketpair(int domain, int type, \ int protocol, int *rsv); } 136 AUE_MKDIR NOPROTO { int mkdir(char *path, int mode); } 137 AUE_RMDIR NOPROTO { int rmdir(char *path); } 138 AUE_UTIMES STD { int freebsd32_utimes(char *path, \ struct timeval32 *tptr); } 139 AUE_NULL OBSOL 4.2 sigreturn 140 AUE_ADJTIME STD { int freebsd32_adjtime( \ struct timeval32 *delta, \ struct timeval32 *olddelta); } 141 AUE_GETPEERNAME OBSOL ogetpeername 142 AUE_SYSCTL OBSOL ogethostid 143 AUE_SYSCTL OBSOL sethostid 144 AUE_GETRLIMIT OBSOL getrlimit 145 AUE_SETRLIMIT OBSOL setrlimit 146 AUE_KILLPG OBSOL killpg 147 AUE_SETSID NOPROTO { int setsid(void); } 148 AUE_QUOTACTL NOPROTO { int quotactl(char *path, int cmd, int uid, \ caddr_t arg); } 149 AUE_O_QUOTA OBSOL oquota 150 AUE_GETSOCKNAME OBSOL ogetsockname ; Syscalls 151-180 inclusive are reserved for vendor-specific ; system calls. (This includes various calls added for compatibity ; with other Unix variants.) ; Some of these calls are now supported by BSD... 151 AUE_NULL UNIMPL sem_lock (BSD/OS 2.x) 152 AUE_NULL UNIMPL sem_wakeup (BSD/OS 2.x) 153 AUE_NULL UNIMPL asyncdaemon (BSD/OS 2.x) ; 154 is initialised by the NLM code, if present. 154 AUE_NULL UNIMPL nlm_syscall ; 155 is initialized by the NFS code, if present. ; XXX this is a problem!!! 155 AUE_NFS_SVC UNIMPL nfssvc 156 AUE_GETDIRENTRIES COMPAT { int freebsd32_getdirentries(int fd, \ char *buf, u_int count, uint32_t *basep); } 157 AUE_STATFS COMPAT4 { int freebsd32_statfs(char *path, \ struct statfs32 *buf); } 158 AUE_FSTATFS COMPAT4 { int freebsd32_fstatfs(int fd, \ struct statfs32 *buf); } 159 AUE_NULL UNIMPL nosys 160 AUE_LGETFH UNIMPL lgetfh 161 AUE_NFS_GETFH NOPROTO { int getfh(char *fname, \ struct fhandle *fhp); } 162 AUE_NULL OBSOL getdomainname 163 AUE_NULL OBSOL setdomainname 164 AUE_NULL OBSOL uname 165 AUE_SYSARCH STD { int freebsd32_sysarch(int op, char *parms); } 166 AUE_RTPRIO NOPROTO { int rtprio(int function, pid_t pid, \ struct rtprio *rtp); } 167 AUE_NULL UNIMPL nosys 168 AUE_NULL UNIMPL nosys 169 AUE_SEMSYS NOSTD { int freebsd32_semsys(int which, int a2, \ int a3, int a4, int a5); } 170 AUE_MSGSYS NOSTD { int freebsd32_msgsys(int which, int a2, \ int a3, int a4, int a5, int a6); } 171 AUE_SHMSYS NOSTD { int freebsd32_shmsys(uint32_t which, uint32_t a2, \ uint32_t a3, uint32_t a4); } 172 AUE_NULL UNIMPL nosys 173 AUE_PREAD COMPAT6 { ssize_t freebsd32_pread(int fd, void *buf, \ size_t nbyte, int pad, \ u_int32_t offset1, u_int32_t offset2); } 174 AUE_PWRITE COMPAT6 { ssize_t freebsd32_pwrite(int fd, \ const void *buf, size_t nbyte, int pad, \ u_int32_t offset1, u_int32_t offset2); } 175 AUE_NULL UNIMPL nosys 176 AUE_NTP_ADJTIME NOPROTO { int ntp_adjtime(struct timex *tp); } 177 AUE_NULL UNIMPL sfork (BSD/OS 2.x) 178 AUE_NULL UNIMPL getdescriptor (BSD/OS 2.x) 179 AUE_NULL UNIMPL setdescriptor (BSD/OS 2.x) 180 AUE_NULL UNIMPL nosys ; Syscalls 181-199 are used by/reserved for BSD 181 AUE_SETGID NOPROTO { int setgid(gid_t gid); } 182 AUE_SETEGID NOPROTO { int setegid(gid_t egid); } 183 AUE_SETEUID NOPROTO { int seteuid(uid_t euid); } 184 AUE_NULL UNIMPL lfs_bmapv 185 AUE_NULL UNIMPL lfs_markv 186 AUE_NULL UNIMPL lfs_segclean 187 AUE_NULL UNIMPL lfs_segwait 188 AUE_STAT STD { int freebsd32_stat(char *path, \ struct stat32 *ub); } 189 AUE_FSTAT STD { int freebsd32_fstat(int fd, \ struct stat32 *ub); } 190 AUE_LSTAT STD { int freebsd32_lstat(char *path, \ struct stat32 *ub); } 191 AUE_PATHCONF NOPROTO { int pathconf(char *path, int name); } 192 AUE_FPATHCONF NOPROTO { int fpathconf(int fd, int name); } 193 AUE_NULL UNIMPL nosys 194 AUE_GETRLIMIT NOPROTO { int getrlimit(u_int which, \ struct rlimit *rlp); } getrlimit \ __getrlimit_args int 195 AUE_SETRLIMIT NOPROTO { int setrlimit(u_int which, \ struct rlimit *rlp); } setrlimit \ __setrlimit_args int 196 AUE_GETDIRENTRIES STD { int freebsd32_getdirentries(int fd, \ char *buf, u_int count, int32_t *basep); } 197 AUE_MMAP COMPAT6 { caddr_t freebsd32_mmap(caddr_t addr, \ size_t len, int prot, int flags, int fd, \ int pad, u_int32_t pos1, u_int32_t pos2); } 198 AUE_NULL NOPROTO { int nosys(void); } __syscall \ __syscall_args int 199 AUE_LSEEK COMPAT6 { off_t freebsd32_lseek(int fd, int pad, \ u_int32_t offset1, u_int32_t offset2, \ int whence); } 200 AUE_TRUNCATE COMPAT6 { int freebsd32_truncate(char *path, \ int pad, u_int32_t length1, \ u_int32_t length2); } 201 AUE_FTRUNCATE COMPAT6 { int freebsd32_ftruncate(int fd, int pad, \ u_int32_t length1, u_int32_t length2); } 202 AUE_SYSCTL STD { int freebsd32_sysctl(int *name, \ u_int namelen, void *old, \ u_int32_t *oldlenp, void *new, \ u_int32_t newlen); } 203 AUE_MLOCK NOPROTO { int mlock(const void *addr, \ size_t len); } 204 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, \ size_t len); } 205 AUE_UNDELETE NOPROTO { int undelete(char *path); } 206 AUE_FUTIMES STD { int freebsd32_futimes(int fd, \ struct timeval32 *tptr); } 207 AUE_GETPGID NOPROTO { int getpgid(pid_t pid); } 208 AUE_NULL UNIMPL newreboot (NetBSD) 209 AUE_POLL NOPROTO { int poll(struct pollfd *fds, u_int nfds, \ int timeout); } ; ; The following are reserved for loadable syscalls ; 210 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 211 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 212 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 213 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 214 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 215 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 216 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 217 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 218 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 219 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int ; ; The following were introduced with NetBSD/4.4Lite-2 ; They are initialized by their respective modules/sysinits ; XXX PROBLEM!! 220 AUE_SEMCTL COMPAT7|NOSTD { int freebsd32_semctl( \ int semid, int semnum, \ int cmd, union semun32 *arg); } 221 AUE_SEMGET NOSTD|NOPROTO { int semget(key_t key, int nsems, \ int semflg); } 222 AUE_SEMOP NOSTD|NOPROTO { int semop(int semid, \ struct sembuf *sops, u_int nsops); } 223 AUE_NULL UNIMPL semconfig 224 AUE_MSGCTL COMPAT7|NOSTD { int freebsd32_msgctl( \ int msqid, int cmd, \ struct msqid_ds32_old *buf); } 225 AUE_MSGGET NOSTD|NOPROTO { int msgget(key_t key, int msgflg); } 226 AUE_MSGSND NOSTD { int freebsd32_msgsnd(int msqid, void *msgp, \ size_t msgsz, int msgflg); } 227 AUE_MSGRCV NOSTD { int freebsd32_msgrcv(int msqid, void *msgp, \ size_t msgsz, long msgtyp, int msgflg); } 228 AUE_SHMAT NOSTD|NOPROTO { int shmat(int shmid, void *shmaddr, \ int shmflg); } 229 AUE_SHMCTL COMPAT7|NOSTD { int freebsd32_shmctl( \ int shmid, int cmd, \ struct shmid_ds32_old *buf); } 230 AUE_SHMDT NOSTD|NOPROTO { int shmdt(void *shmaddr); } 231 AUE_SHMGET NOSTD|NOPROTO { int shmget(key_t key, int size, \ int shmflg); } ; 232 AUE_NULL STD { int freebsd32_clock_gettime(clockid_t clock_id, \ struct timespec32 *tp); } 233 AUE_CLOCK_SETTIME STD { int freebsd32_clock_settime(clockid_t clock_id, \ const struct timespec32 *tp); } 234 AUE_NULL STD { int freebsd32_clock_getres(clockid_t clock_id, \ struct timespec32 *tp); } 235 AUE_NULL UNIMPL timer_create 236 AUE_NULL UNIMPL timer_delete 237 AUE_NULL UNIMPL timer_settime 238 AUE_NULL UNIMPL timer_gettime 239 AUE_NULL UNIMPL timer_getoverrun 240 AUE_NULL STD { int freebsd32_nanosleep( \ const struct timespec32 *rqtp, \ struct timespec32 *rmtp); } 241 AUE_NULL UNIMPL nosys 242 AUE_NULL UNIMPL nosys 243 AUE_NULL UNIMPL nosys 244 AUE_NULL UNIMPL nosys 245 AUE_NULL UNIMPL nosys 246 AUE_NULL UNIMPL nosys 247 AUE_NULL UNIMPL nosys 248 AUE_NULL UNIMPL ntp_gettime 249 AUE_NULL UNIMPL nosys ; syscall numbers initially used in OpenBSD 250 AUE_MINHERIT NOPROTO { int minherit(void *addr, size_t len, \ int inherit); } 251 AUE_RFORK NOPROTO { int rfork(int flags); } 252 AUE_POLL NOPROTO { int openbsd_poll(struct pollfd *fds, \ u_int nfds, int timeout); } 253 AUE_ISSETUGID NOPROTO { int issetugid(void); } 254 AUE_LCHOWN NOPROTO { int lchown(char *path, int uid, int gid); } 255 AUE_NULL NOSTD { int freebsd32_aio_read( \ struct aiocb32 *aiocbp); } 256 AUE_NULL NOSTD { int freebsd32_aio_write( \ struct aiocb32 *aiocbp); } 257 AUE_NULL NOSTD { int freebsd32_lio_listio(int mode, \ struct aiocb32 * const *acb_list, \ int nent, struct sigevent *sig); } 258 AUE_NULL UNIMPL nosys 259 AUE_NULL UNIMPL nosys 260 AUE_NULL UNIMPL nosys 261 AUE_NULL UNIMPL nosys 262 AUE_NULL UNIMPL nosys 263 AUE_NULL UNIMPL nosys 264 AUE_NULL UNIMPL nosys 265 AUE_NULL UNIMPL nosys 266 AUE_NULL UNIMPL nosys 267 AUE_NULL UNIMPL nosys 268 AUE_NULL UNIMPL nosys 269 AUE_NULL UNIMPL nosys 270 AUE_NULL UNIMPL nosys 271 AUE_NULL UNIMPL nosys 272 AUE_O_GETDENTS NOPROTO { int getdents(int fd, char *buf, \ size_t count); } 273 AUE_NULL UNIMPL nosys 274 AUE_LCHMOD NOPROTO { int lchmod(char *path, mode_t mode); } 275 AUE_LCHOWN NOPROTO { int lchown(char *path, uid_t uid, \ gid_t gid); } netbsd_lchown \ lchown_args int 276 AUE_LUTIMES STD { int freebsd32_lutimes(char *path, \ struct timeval32 *tptr); } 277 AUE_MSYNC NOPROTO { int msync(void *addr, size_t len, \ int flags); } netbsd_msync msync_args int 278 AUE_STAT NOPROTO { int nstat(char *path, struct nstat *ub); } 279 AUE_FSTAT NOPROTO { int nfstat(int fd, struct nstat *sb); } 280 AUE_LSTAT NOPROTO { int nlstat(char *path, struct nstat *ub); } 281 AUE_NULL UNIMPL nosys 282 AUE_NULL UNIMPL nosys 283 AUE_NULL UNIMPL nosys 284 AUE_NULL UNIMPL nosys 285 AUE_NULL UNIMPL nosys 286 AUE_NULL UNIMPL nosys 287 AUE_NULL UNIMPL nosys 288 AUE_NULL UNIMPL nosys ; 289 and 290 from NetBSD (OpenBSD: 267 and 268) 289 AUE_PREADV STD { ssize_t freebsd32_preadv(int fd, \ struct iovec32 *iovp, \ u_int iovcnt, \ u_int32_t offset1, u_int32_t offset2); } 290 AUE_PWRITEV STD { ssize_t freebsd32_pwritev(int fd, \ struct iovec32 *iovp, \ u_int iovcnt, \ u_int32_t offset1, u_int32_t offset2); } 291 AUE_NULL UNIMPL nosys 292 AUE_NULL UNIMPL nosys 293 AUE_NULL UNIMPL nosys 294 AUE_NULL UNIMPL nosys 295 AUE_NULL UNIMPL nosys 296 AUE_NULL UNIMPL nosys ; XXX 297 is 300 in NetBSD 297 AUE_FHSTATFS COMPAT4 { int freebsd32_fhstatfs( \ const struct fhandle *u_fhp, \ struct statfs32 *buf); } 298 AUE_FHOPEN NOPROTO { int fhopen(const struct fhandle *u_fhp, \ int flags); } 299 AUE_FHSTAT NOPROTO { int fhstat(const struct fhandle *u_fhp, \ struct stat *sb); } ; syscall numbers for FreeBSD 300 AUE_NULL NOPROTO { int modnext(int modid); } 301 AUE_NULL STD { int freebsd32_modstat(int modid, \ struct module_stat32* stat); } 302 AUE_NULL NOPROTO { int modfnext(int modid); } 303 AUE_NULL NOPROTO { int modfind(const char *name); } 304 AUE_MODLOAD NOPROTO { int kldload(const char *file); } 305 AUE_MODUNLOAD NOPROTO { int kldunload(int fileid); } 306 AUE_NULL NOPROTO { int kldfind(const char *file); } 307 AUE_NULL NOPROTO { int kldnext(int fileid); } 308 AUE_NULL STD { int freebsd32_kldstat(int fileid, \ struct kld32_file_stat* stat); } 309 AUE_NULL NOPROTO { int kldfirstmod(int fileid); } 310 AUE_GETSID NOPROTO { int getsid(pid_t pid); } 311 AUE_SETRESUID NOPROTO { int setresuid(uid_t ruid, uid_t euid, \ uid_t suid); } 312 AUE_SETRESGID NOPROTO { int setresgid(gid_t rgid, gid_t egid, \ gid_t sgid); } 313 AUE_NULL OBSOL signanosleep 314 AUE_NULL NOSTD { int freebsd32_aio_return( \ struct aiocb32 *aiocbp); } 315 AUE_NULL NOSTD { int freebsd32_aio_suspend( \ struct aiocb32 * const * aiocbp, int nent, \ const struct timespec32 *timeout); } 316 AUE_NULL NOSTD { int freebsd32_aio_cancel(int fd, \ struct aiocb32 *aiocbp); } 317 AUE_NULL NOSTD { int freebsd32_aio_error( \ struct aiocb32 *aiocbp); } 318 AUE_NULL NOSTD { int freebsd32_oaio_read( \ struct oaiocb32 *aiocbp); } 319 AUE_NULL NOSTD { int freebsd32_oaio_write( \ struct oaiocb32 *aiocbp); } 320 AUE_NULL NOSTD { int freebsd32_olio_listio(int mode, \ struct oaiocb32 * const *acb_list, \ int nent, struct osigevent32 *sig); } 321 AUE_NULL NOPROTO { int yield(void); } 322 AUE_NULL OBSOL thr_sleep 323 AUE_NULL OBSOL thr_wakeup 324 AUE_MLOCKALL NOPROTO { int mlockall(int how); } 325 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } 326 AUE_GETCWD NOPROTO { int __getcwd(u_char *buf, u_int buflen); } 327 AUE_NULL NOPROTO { int sched_setparam (pid_t pid, \ const struct sched_param *param); } 328 AUE_NULL NOPROTO { int sched_getparam (pid_t pid, \ struct sched_param *param); } 329 AUE_NULL NOPROTO { int sched_setscheduler (pid_t pid, \ int policy, \ const struct sched_param *param); } 330 AUE_NULL NOPROTO { int sched_getscheduler (pid_t pid); } 331 AUE_NULL NOPROTO { int sched_yield (void); } 332 AUE_NULL NOPROTO { int sched_get_priority_max (int policy); } 333 AUE_NULL NOPROTO { int sched_get_priority_min (int policy); } 334 AUE_NULL NOPROTO { int sched_rr_get_interval (pid_t pid, \ struct timespec *interval); } 335 AUE_NULL NOPROTO { int utrace(const void *addr, size_t len); } 336 AUE_SENDFILE COMPAT4 { int freebsd32_sendfile(int fd, int s, \ u_int32_t offset1, u_int32_t offset2, \ size_t nbytes, struct sf_hdtr32 *hdtr, \ off_t *sbytes, int flags); } 337 AUE_NULL NOPROTO { int kldsym(int fileid, int cmd, \ void *data); } 338 AUE_JAIL STD { int freebsd32_jail(struct jail32 *jail); } 339 AUE_NULL UNIMPL pioctl 340 AUE_SIGPROCMASK NOPROTO { int sigprocmask(int how, \ const sigset_t *set, sigset_t *oset); } 341 AUE_SIGSUSPEND NOPROTO { int sigsuspend(const sigset_t *sigmask); } 342 AUE_SIGACTION COMPAT4 { int freebsd32_sigaction(int sig, \ struct sigaction32 *act, \ struct sigaction32 *oact); } 343 AUE_SIGPENDING NOPROTO { int sigpending(sigset_t *set); } 344 AUE_SIGRETURN COMPAT4 { int freebsd32_sigreturn( \ const struct freebsd4_freebsd32_ucontext *sigcntxp); } 345 AUE_SIGWAIT STD { int freebsd32_sigtimedwait(const sigset_t *set, \ siginfo_t *info, \ const struct timespec *timeout); } 346 AUE_NULL STD { int freebsd32_sigwaitinfo(const sigset_t *set, \ siginfo_t *info); } 347 AUE_NULL NOPROTO { int __acl_get_file(const char *path, \ acl_type_t type, struct acl *aclp); } 348 AUE_NULL NOPROTO { int __acl_set_file(const char *path, \ acl_type_t type, struct acl *aclp); } 349 AUE_NULL NOPROTO { int __acl_get_fd(int filedes, \ acl_type_t type, struct acl *aclp); } 350 AUE_NULL NOPROTO { int __acl_set_fd(int filedes, \ acl_type_t type, struct acl *aclp); } 351 AUE_NULL NOPROTO { int __acl_delete_file(const char *path, \ acl_type_t type); } 352 AUE_NULL NOPROTO { int __acl_delete_fd(int filedes, \ acl_type_t type); } 353 AUE_NULL NOPROTO { int __acl_aclcheck_file(const char *path, \ acl_type_t type, struct acl *aclp); } 354 AUE_NULL NOPROTO { int __acl_aclcheck_fd(int filedes, \ acl_type_t type, struct acl *aclp); } 355 AUE_EXTATTRCTL NOPROTO { int extattrctl(const char *path, int cmd, \ const char *filename, int attrnamespace, \ const char *attrname); } 356 AUE_EXTATTR_SET_FILE NOPROTO { int extattr_set_file( \ const char *path, int attrnamespace, \ const char *attrname, void *data, \ size_t nbytes); } 357 AUE_EXTATTR_GET_FILE NOPROTO { ssize_t extattr_get_file( \ const char *path, int attrnamespace, \ const char *attrname, void *data, \ size_t nbytes); } 358 AUE_EXTATTR_DELETE_FILE NOPROTO { int extattr_delete_file( \ const char *path, int attrnamespace, \ const char *attrname); } 359 AUE_NULL NOSTD { int freebsd32_aio_waitcomplete( \ struct aiocb32 **aiocbp, \ struct timespec32 *timeout); } 360 AUE_GETRESUID NOPROTO { int getresuid(uid_t *ruid, uid_t *euid, \ uid_t *suid); } 361 AUE_GETRESGID NOPROTO { int getresgid(gid_t *rgid, gid_t *egid, \ gid_t *sgid); } 362 AUE_KQUEUE NOPROTO { int kqueue(void); } 363 AUE_NULL STD { int freebsd32_kevent(int fd, \ const struct kevent32 *changelist, \ int nchanges, \ struct kevent32 *eventlist, int nevents, \ const struct timespec32 *timeout); } 364 AUE_NULL UNIMPL __cap_get_proc 365 AUE_NULL UNIMPL __cap_set_proc 366 AUE_NULL UNIMPL __cap_get_fd 367 AUE_NULL UNIMPL __cap_get_file 368 AUE_NULL UNIMPL __cap_set_fd 369 AUE_NULL UNIMPL __cap_set_file 370 AUE_NULL UNIMPL nosys 371 AUE_EXTATTR_SET_FD NOPROTO { int extattr_set_fd(int fd, \ int attrnamespace, const char *attrname, \ void *data, size_t nbytes); } 372 AUE_EXTATTR_GET_FD NOPROTO { ssize_t extattr_get_fd(int fd, \ int attrnamespace, const char *attrname, \ void *data, size_t nbytes); } 373 AUE_EXTATTR_DELETE_FD NOPROTO { int extattr_delete_fd(int fd, \ int attrnamespace, \ const char *attrname); } 374 AUE_NULL NOPROTO { int __setugid(int flag); } 375 AUE_NULL UNIMPL nfsclnt -376 AUE_EACCESS NOPROTO { int eaccess(char *path, int flags); } +376 AUE_EACCESS NOPROTO { int eaccess(char *path, int amode); } 377 AUE_NULL UNIMPL afs_syscall 378 AUE_NMOUNT STD { int freebsd32_nmount(struct iovec32 *iovp, \ unsigned int iovcnt, int flags); } 379 AUE_NULL UNIMPL kse_exit 380 AUE_NULL UNIMPL kse_wakeup 381 AUE_NULL UNIMPL kse_create 382 AUE_NULL UNIMPL kse_thr_interrupt 383 AUE_NULL UNIMPL kse_release 384 AUE_NULL UNIMPL __mac_get_proc 385 AUE_NULL UNIMPL __mac_set_proc 386 AUE_NULL UNIMPL __mac_get_fd 387 AUE_NULL UNIMPL __mac_get_file 388 AUE_NULL UNIMPL __mac_set_fd 389 AUE_NULL UNIMPL __mac_set_file 390 AUE_NULL NOPROTO { int kenv(int what, const char *name, \ char *value, int len); } 391 AUE_LCHFLAGS NOPROTO { int lchflags(const char *path, int flags); } 392 AUE_NULL NOPROTO { int uuidgen(struct uuid *store, \ int count); } 393 AUE_SENDFILE STD { int freebsd32_sendfile(int fd, int s, \ u_int32_t offset1, u_int32_t offset2, \ size_t nbytes, struct sf_hdtr32 *hdtr, \ off_t *sbytes, int flags); } 394 AUE_NULL UNIMPL mac_syscall 395 AUE_GETFSSTAT NOPROTO { int getfsstat(struct statfs *buf, \ long bufsize, int flags); } 396 AUE_STATFS NOPROTO { int statfs(char *path, \ struct statfs *buf); } 397 AUE_FSTATFS NOPROTO { int fstatfs(int fd, struct statfs *buf); } 398 AUE_FHSTATFS NOPROTO { int fhstatfs(const struct fhandle *u_fhp, \ struct statfs *buf); } 399 AUE_NULL UNIMPL nosys 400 AUE_NULL NOSTD|NOPROTO { int ksem_close(semid_t id); } 401 AUE_NULL NOSTD|NOPROTO { int ksem_post(semid_t id); } 402 AUE_NULL NOSTD|NOPROTO { int ksem_wait(semid_t id); } 403 AUE_NULL NOSTD|NOPROTO { int ksem_trywait(semid_t id); } 404 AUE_NULL NOSTD { int freebsd32_ksem_init(semid_t *idp, \ unsigned int value); } 405 AUE_NULL NOSTD { int freebsd32_ksem_open(semid_t *idp, \ const char *name, int oflag, \ mode_t mode, unsigned int value); } 406 AUE_NULL NOSTD|NOPROTO { int ksem_unlink(const char *name); } 407 AUE_NULL NOSTD|NOPROTO { int ksem_getvalue(semid_t id, \ int *val); } 408 AUE_NULL NOSTD|NOPROTO { int ksem_destroy(semid_t id); } 409 AUE_NULL UNIMPL __mac_get_pid 410 AUE_NULL UNIMPL __mac_get_link 411 AUE_NULL UNIMPL __mac_set_link 412 AUE_EXTATTR_SET_LINK NOPROTO { int extattr_set_link( \ const char *path, int attrnamespace, \ const char *attrname, void *data, \ size_t nbytes); } 413 AUE_EXTATTR_GET_LINK NOPROTO { ssize_t extattr_get_link( \ const char *path, int attrnamespace, \ const char *attrname, void *data, \ size_t nbytes); } 414 AUE_EXTATTR_DELETE_LINK NOPROTO { int extattr_delete_link( \ const char *path, int attrnamespace, \ const char *attrname); } 415 AUE_NULL UNIMPL __mac_execve 416 AUE_SIGACTION STD { int freebsd32_sigaction(int sig, \ struct sigaction32 *act, \ struct sigaction32 *oact); } 417 AUE_SIGRETURN STD { int freebsd32_sigreturn( \ const struct freebsd32_ucontext *sigcntxp); } 418 AUE_NULL UNIMPL __xstat 419 AUE_NULL UNIMPL __xfstat 420 AUE_NULL UNIMPL __xlstat 421 AUE_NULL STD { int freebsd32_getcontext( \ struct freebsd32_ucontext *ucp); } 422 AUE_NULL STD { int freebsd32_setcontext( \ const struct freebsd32_ucontext *ucp); } 423 AUE_NULL STD { int freebsd32_swapcontext( \ struct freebsd32_ucontext *oucp, \ const struct freebsd32_ucontext *ucp); } 424 AUE_SWAPOFF UNIMPL swapoff 425 AUE_NULL NOPROTO { int __acl_get_link(const char *path, \ acl_type_t type, struct acl *aclp); } 426 AUE_NULL NOPROTO { int __acl_set_link(const char *path, \ acl_type_t type, struct acl *aclp); } 427 AUE_NULL NOPROTO { int __acl_delete_link(const char *path, \ acl_type_t type); } 428 AUE_NULL NOPROTO { int __acl_aclcheck_link(const char *path, \ acl_type_t type, struct acl *aclp); } 429 AUE_SIGWAIT NOPROTO { int sigwait(const sigset_t *set, \ int *sig); } 430 AUE_NULL UNIMPL thr_create; 431 AUE_NULL NOPROTO { void thr_exit(long *state); } 432 AUE_NULL NOPROTO { int thr_self(long *id); } 433 AUE_NULL NOPROTO { int thr_kill(long id, int sig); } 434 AUE_NULL STD { int freebsd32_umtx_lock(struct umtx *umtx); } 435 AUE_NULL STD { int freebsd32_umtx_unlock(struct umtx *umtx); } 436 AUE_NULL NOPROTO { int jail_attach(int jid); } 437 AUE_EXTATTR_LIST_FD NOPROTO { ssize_t extattr_list_fd(int fd, \ int attrnamespace, void *data, \ size_t nbytes); } 438 AUE_EXTATTR_LIST_FILE NOPROTO { ssize_t extattr_list_file( \ const char *path, int attrnamespace, \ void *data, size_t nbytes); } 439 AUE_EXTATTR_LIST_LINK NOPROTO { ssize_t extattr_list_link( \ const char *path, int attrnamespace, \ void *data, size_t nbytes); } 440 AUE_NULL UNIMPL kse_switchin 441 AUE_NULL NOSTD { int freebsd32_ksem_timedwait(semid_t id, \ const struct timespec32 *abstime); } 442 AUE_NULL STD { int freebsd32_thr_suspend( \ const struct timespec32 *timeout); } 443 AUE_NULL NOPROTO { int thr_wake(long id); } 444 AUE_MODUNLOAD NOPROTO { int kldunloadf(int fileid, int flags); } 445 AUE_AUDIT NOPROTO { int audit(const void *record, \ u_int length); } 446 AUE_AUDITON NOPROTO { int auditon(int cmd, void *data, \ u_int length); } 447 AUE_GETAUID NOPROTO { int getauid(uid_t *auid); } 448 AUE_SETAUID NOPROTO { int setauid(uid_t *auid); } 449 AUE_GETAUDIT NOPROTO { int getaudit(struct auditinfo *auditinfo); } 450 AUE_SETAUDIT NOPROTO { int setaudit(struct auditinfo *auditinfo); } 451 AUE_GETAUDIT_ADDR NOPROTO { int getaudit_addr( \ struct auditinfo_addr *auditinfo_addr, \ u_int length); } 452 AUE_SETAUDIT_ADDR NOPROTO { int setaudit_addr( \ struct auditinfo_addr *auditinfo_addr, \ u_int length); } 453 AUE_AUDITCTL NOPROTO { int auditctl(char *path); } 454 AUE_NULL STD { int freebsd32_umtx_op(void *obj, int op,\ u_long val, void *uaddr, \ void *uaddr2); } 455 AUE_NULL STD { int freebsd32_thr_new( \ struct thr_param32 *param, \ int param_size); } 456 AUE_NULL NOPROTO { int sigqueue(pid_t pid, int signum, \ void *value); } 457 AUE_NULL NOSTD { int freebsd32_kmq_open( \ const char *path, int flags, mode_t mode, \ const struct mq_attr32 *attr); } 458 AUE_NULL NOSTD { int freebsd32_kmq_setattr(int mqd, \ const struct mq_attr32 *attr, \ struct mq_attr32 *oattr); } 459 AUE_NULL NOSTD { int freebsd32_kmq_timedreceive(int mqd, \ char *msg_ptr, size_t msg_len, \ unsigned *msg_prio, \ const struct timespec32 *abs_timeout); } 460 AUE_NULL NOSTD { int freebsd32_kmq_timedsend(int mqd, \ const char *msg_ptr, size_t msg_len,\ unsigned msg_prio, \ const struct timespec32 *abs_timeout);} 461 AUE_NULL NOPROTO|NOSTD { int kmq_notify(int mqd, \ const struct sigevent *sigev); } 462 AUE_NULL NOPROTO|NOSTD { int kmq_unlink(const char *path); } 463 AUE_NULL NOPROTO { int abort2(const char *why, int nargs, void **args); } 464 AUE_NULL NOPROTO { int thr_set_name(long id, const char *name); } 465 AUE_NULL NOSTD { int freebsd32_aio_fsync(int op, \ struct aiocb32 *aiocbp); } 466 AUE_RTPRIO NOPROTO { int rtprio_thread(int function, \ lwpid_t lwpid, struct rtprio *rtp); } 467 AUE_NULL UNIMPL nosys 468 AUE_NULL UNIMPL nosys 469 AUE_NULL UNIMPL __getpath_fromfd 470 AUE_NULL UNIMPL __getpath_fromaddr 471 AUE_NULL NOPROTO { int sctp_peeloff(int sd, uint32_t name); } 472 AUE_NULL NOPROTO { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \ caddr_t to, __socklen_t tolen, \ struct sctp_sndrcvinfo *sinfo, int flags); } 473 AUE_NULL NOPROTO { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \ caddr_t to, __socklen_t tolen, \ struct sctp_sndrcvinfo *sinfo, int flags); } 474 AUE_NULL NOPROTO { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \ struct sockaddr * from, __socklen_t *fromlenaddr, \ struct sctp_sndrcvinfo *sinfo, int *msg_flags); } #ifdef PAD64_REQUIRED 475 AUE_PREAD STD { ssize_t freebsd32_pread(int fd, \ void *buf,size_t nbyte, \ int pad, \ u_int32_t offset1, u_int32_t offset2); } 476 AUE_PWRITE STD { ssize_t freebsd32_pwrite(int fd, \ const void *buf, size_t nbyte, \ int pad, \ u_int32_t offset1, u_int32_t offset2); } 477 AUE_MMAP STD { caddr_t freebsd32_mmap(caddr_t addr, \ size_t len, int prot, int flags, int fd, \ int pad, \ u_int32_t pos1, u_int32_t pos2); } 478 AUE_LSEEK STD { off_t freebsd32_lseek(int fd, \ int pad, \ u_int32_t offset1, u_int32_t offset2, \ int whence); } 479 AUE_TRUNCATE STD { int freebsd32_truncate(char *path, \ int pad, \ u_int32_t length1, u_int32_t length2); } 480 AUE_FTRUNCATE STD { int freebsd32_ftruncate(int fd, \ int pad, \ u_int32_t length1, u_int32_t length2); } #else 475 AUE_PREAD STD { ssize_t freebsd32_pread(int fd, \ void *buf,size_t nbyte, \ u_int32_t offset1, u_int32_t offset2); } 476 AUE_PWRITE STD { ssize_t freebsd32_pwrite(int fd, \ const void *buf, size_t nbyte, \ u_int32_t offset1, u_int32_t offset2); } 477 AUE_MMAP STD { caddr_t freebsd32_mmap(caddr_t addr, \ size_t len, int prot, int flags, int fd, \ u_int32_t pos1, u_int32_t pos2); } 478 AUE_LSEEK STD { off_t freebsd32_lseek(int fd, \ u_int32_t offset1, u_int32_t offset2, \ int whence); } 479 AUE_TRUNCATE STD { int freebsd32_truncate(char *path, \ u_int32_t length1, u_int32_t length2); } 480 AUE_FTRUNCATE STD { int freebsd32_ftruncate(int fd, \ u_int32_t length1, u_int32_t length2); } #endif 481 AUE_KILL NOPROTO { int thr_kill2(pid_t pid, long id, int sig); } 482 AUE_SHMOPEN NOPROTO { int shm_open(const char *path, int flags, \ mode_t mode); } 483 AUE_SHMUNLINK NOPROTO { int shm_unlink(const char *path); } 484 AUE_NULL NOPROTO { int cpuset(cpusetid_t *setid); } #ifdef PAD64_REQUIRED 485 AUE_NULL STD { int freebsd32_cpuset_setid(cpuwhich_t which, \ int pad, \ u_int32_t id1, u_int32_t id2, \ cpusetid_t setid); } #else 485 AUE_NULL STD { int freebsd32_cpuset_setid(cpuwhich_t which, \ u_int32_t id1, u_int32_t id2, \ cpusetid_t setid); } #endif 486 AUE_NULL STD { int freebsd32_cpuset_getid(cpulevel_t level, \ cpuwhich_t which, \ u_int32_t id1, u_int32_t id2, \ cpusetid_t *setid); } 487 AUE_NULL STD { int freebsd32_cpuset_getaffinity( \ cpulevel_t level, cpuwhich_t which, \ u_int32_t id1, u_int32_t id2, \ size_t cpusetsize, \ cpuset_t *mask); } 488 AUE_NULL STD { int freebsd32_cpuset_setaffinity( \ cpulevel_t level, cpuwhich_t which, \ u_int32_t id1, u_int32_t id2, \ size_t cpusetsize, \ const cpuset_t *mask); } -489 AUE_FACCESSAT NOPROTO { int faccessat(int fd, char *path, int mode, \ +489 AUE_FACCESSAT NOPROTO { int faccessat(int fd, char *path, int amode, \ int flag); } 490 AUE_FCHMODAT NOPROTO { int fchmodat(int fd, const char *path, \ mode_t mode, int flag); } 491 AUE_FCHOWNAT NOPROTO { int fchownat(int fd, char *path, uid_t uid, \ gid_t gid, int flag); } 492 AUE_FEXECVE STD { int freebsd32_fexecve(int fd, \ u_int32_t *argv, u_int32_t *envv); } 493 AUE_FSTATAT STD { int freebsd32_fstatat(int fd, char *path, \ struct stat *buf, int flag); } 494 AUE_FUTIMESAT STD { int freebsd32_futimesat(int fd, char *path, \ struct timeval *times); } 495 AUE_LINKAT NOPROTO { int linkat(int fd1, char *path1, int fd2, \ char *path2, int flag); } 496 AUE_MKDIRAT NOPROTO { int mkdirat(int fd, char *path, \ mode_t mode); } 497 AUE_MKFIFOAT NOPROTO { int mkfifoat(int fd, char *path, \ mode_t mode); } 498 AUE_MKNODAT NOPROTO { int mknodat(int fd, char *path, \ mode_t mode, dev_t dev); } 499 AUE_OPENAT_RWTC NOPROTO { int openat(int fd, char *path, int flag, \ mode_t mode); } 500 AUE_READLINKAT NOPROTO { int readlinkat(int fd, char *path, char *buf, \ size_t bufsize); } 501 AUE_RENAMEAT NOPROTO { int renameat(int oldfd, char *old, int newfd, \ const char *new); } 502 AUE_SYMLINKAT NOPROTO { int symlinkat(char *path1, int fd, \ char *path2); } 503 AUE_UNLINKAT NOPROTO { int unlinkat(int fd, char *path, \ int flag); } 504 AUE_POSIX_OPENPT NOPROTO { int posix_openpt(int flags); } ; 505 is initialised by the kgssapi code, if present. 505 AUE_NULL UNIMPL gssd_syscall 506 AUE_NULL STD { int freebsd32_jail_get(struct iovec32 *iovp, \ unsigned int iovcnt, int flags); } 507 AUE_NULL STD { int freebsd32_jail_set(struct iovec32 *iovp, \ unsigned int iovcnt, int flags); } 508 AUE_NULL NOPROTO { int jail_remove(int jid); } 509 AUE_CLOSEFROM NOPROTO { int closefrom(int lowfd); } 510 AUE_SEMCTL NOSTD { int freebsd32_semctl(int semid, int semnum, \ int cmd, union semun32 *arg); } 511 AUE_MSGCTL NOSTD { int freebsd32_msgctl(int msqid, int cmd, \ struct msqid_ds32 *buf); } 512 AUE_SHMCTL NOSTD { int freebsd32_shmctl(int shmid, int cmd, \ struct shmid_ds32 *buf); } 513 AUE_LPATHCONF NOPROTO { int lpathconf(char *path, int name); } 514 AUE_CAP_NEW NOPROTO { int cap_new(int fd, u_int64_t rights); } 515 AUE_CAP_GETRIGHTS NOPROTO { int cap_getrights(int fd, \ u_int64_t *rightsp); } 516 AUE_CAP_ENTER NOPROTO { int cap_enter(void); } 517 AUE_CAP_GETMODE NOPROTO { int cap_getmode(u_int *modep); } 518 AUE_PDFORK UNIMPL pdfork 519 AUE_PDKILL UNIMPL pdkill 520 AUE_PDGETPID UNIMPL pdgetpid 521 AUE_PDWAIT UNIMPL pdwait 522 AUE_SELECT STD { int freebsd32_pselect(int nd, fd_set *in, \ fd_set *ou, fd_set *ex, \ const struct timespec32 *ts, \ const sigset_t *sm); } 523 AUE_NULL NOPROTO { int getloginclass(char *namebuf, \ size_t namelen); } 524 AUE_NULL NOPROTO { int setloginclass(const char *namebuf); } 525 AUE_NULL NOPROTO { int rctl_get_racct(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 526 AUE_NULL NOPROTO { int rctl_get_rules(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 527 AUE_NULL NOPROTO { int rctl_get_limits(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 528 AUE_NULL NOPROTO { int rctl_add_rule(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 529 AUE_NULL NOPROTO { int rctl_remove_rule(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 530 AUE_NULL STD { int freebsd32_posix_fallocate(int fd,\ uint32_t offset1, uint32_t offset2,\ uint32_t len1, uint32_t len2); } 531 AUE_NULL STD { int freebsd32_posix_fadvise(int fd, \ uint32_t offset1, uint32_t offset2,\ uint32_t len1, uint32_t len2, \ int advice); } diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 9cbc3a2cee04..97e4e0485c7a 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -1,1532 +1,1532 @@ /*- * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "opt_compat.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef COMPAT_LINUX32 #include #include #else #include #include #endif #include #include int linux_creat(struct thread *td, struct linux_creat_args *args) { char *path; int error; LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(creat)) printf(ARGS(creat, "%s, %d"), path, args->mode); #endif error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC, args->mode); LFREEPATH(path); return (error); } static int linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode) { struct proc *p = td->td_proc; struct file *fp; int fd; int bsd_flags, error; bsd_flags = 0; switch (l_flags & LINUX_O_ACCMODE) { case LINUX_O_WRONLY: bsd_flags |= O_WRONLY; break; case LINUX_O_RDWR: bsd_flags |= O_RDWR; break; default: bsd_flags |= O_RDONLY; } if (l_flags & LINUX_O_NDELAY) bsd_flags |= O_NONBLOCK; if (l_flags & LINUX_O_APPEND) bsd_flags |= O_APPEND; if (l_flags & LINUX_O_SYNC) bsd_flags |= O_FSYNC; if (l_flags & LINUX_O_NONBLOCK) bsd_flags |= O_NONBLOCK; if (l_flags & LINUX_FASYNC) bsd_flags |= O_ASYNC; if (l_flags & LINUX_O_CREAT) bsd_flags |= O_CREAT; if (l_flags & LINUX_O_TRUNC) bsd_flags |= O_TRUNC; if (l_flags & LINUX_O_EXCL) bsd_flags |= O_EXCL; if (l_flags & LINUX_O_NOCTTY) bsd_flags |= O_NOCTTY; if (l_flags & LINUX_O_DIRECT) bsd_flags |= O_DIRECT; if (l_flags & LINUX_O_NOFOLLOW) bsd_flags |= O_NOFOLLOW; if (l_flags & LINUX_O_DIRECTORY) bsd_flags |= O_DIRECTORY; /* XXX LINUX_O_NOATIME: unable to be easily implemented. */ error = kern_openat(td, dirfd, path, UIO_SYSSPACE, bsd_flags, mode); if (!error) { fd = td->td_retval[0]; /* * XXX In between kern_open() and fget(), another process * having the same filedesc could use that fd without * checking below. */ error = fget(td, fd, CAP_IOCTL, &fp); if (!error) { sx_slock(&proctree_lock); PROC_LOCK(p); if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { PROC_UNLOCK(p); sx_unlock(&proctree_lock); if (fp->f_type == DTYPE_VNODE) (void) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred, td); } else { PROC_UNLOCK(p); sx_sunlock(&proctree_lock); } fdrop(fp, td); /* * XXX as above, fdrop()/kern_close() pair is racy. */ if (error) kern_close(td, fd); } } #ifdef DEBUG if (ldebug(open)) printf(LMSG("open returns error %d"), error); #endif LFREEPATH(path); return (error); } int linux_openat(struct thread *td, struct linux_openat_args *args) { char *path; int dfd; dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; if (args->flags & LINUX_O_CREAT) LCONVPATH_AT(td, args->filename, &path, 1, dfd); else LCONVPATH_AT(td, args->filename, &path, 0, dfd); #ifdef DEBUG if (ldebug(openat)) printf(ARGS(openat, "%i, %s, 0x%x, 0x%x"), args->dfd, path, args->flags, args->mode); #endif return (linux_common_open(td, dfd, path, args->flags, args->mode)); } int linux_open(struct thread *td, struct linux_open_args *args) { char *path; if (args->flags & LINUX_O_CREAT) LCONVPATHCREAT(td, args->path, &path); else LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(open)) printf(ARGS(open, "%s, 0x%x, 0x%x"), path, args->flags, args->mode); #endif return (linux_common_open(td, AT_FDCWD, path, args->flags, args->mode)); } int linux_lseek(struct thread *td, struct linux_lseek_args *args) { struct lseek_args /* { int fd; int pad; off_t offset; int whence; } */ tmp_args; int error; #ifdef DEBUG if (ldebug(lseek)) printf(ARGS(lseek, "%d, %ld, %d"), args->fdes, (long)args->off, args->whence); #endif tmp_args.fd = args->fdes; tmp_args.offset = (off_t)args->off; tmp_args.whence = args->whence; error = sys_lseek(td, &tmp_args); return error; } int linux_llseek(struct thread *td, struct linux_llseek_args *args) { struct lseek_args bsd_args; int error; off_t off; #ifdef DEBUG if (ldebug(llseek)) printf(ARGS(llseek, "%d, %d:%d, %d"), args->fd, args->ohigh, args->olow, args->whence); #endif off = (args->olow) | (((off_t) args->ohigh) << 32); bsd_args.fd = args->fd; bsd_args.offset = off; bsd_args.whence = args->whence; if ((error = sys_lseek(td, &bsd_args))) return error; if ((error = copyout(td->td_retval, args->res, sizeof (off_t)))) return error; td->td_retval[0] = 0; return 0; } int linux_readdir(struct thread *td, struct linux_readdir_args *args) { struct linux_getdents_args lda; lda.fd = args->fd; lda.dent = args->dent; lda.count = 1; return linux_getdents(td, &lda); } /* * Note that linux_getdents(2) and linux_getdents64(2) have the same * arguments. They only differ in the definition of struct dirent they * operate on. We use this to common the code, with the exception of * accessing struct dirent. Note that linux_readdir(2) is implemented * by means of linux_getdents(2). In this case we never operate on * struct dirent64 and thus don't need to handle it... */ struct l_dirent { l_ulong d_ino; l_off_t d_off; l_ushort d_reclen; char d_name[LINUX_NAME_MAX + 1]; }; struct l_dirent64 { uint64_t d_ino; int64_t d_off; l_ushort d_reclen; u_char d_type; char d_name[LINUX_NAME_MAX + 1]; }; /* * Linux uses the last byte in the dirent buffer to store d_type, * at least glibc-2.7 requires it. That is why l_dirent is padded with 2 bytes. */ #define LINUX_RECLEN(namlen) \ roundup((offsetof(struct l_dirent, d_name) + (namlen) + 2), \ sizeof(l_ulong)) #define LINUX_RECLEN64(namlen) \ roundup((offsetof(struct l_dirent64, d_name) + (namlen) + 1), \ sizeof(uint64_t)) #define LINUX_MAXRECLEN max(LINUX_RECLEN(LINUX_NAME_MAX), \ LINUX_RECLEN64(LINUX_NAME_MAX)) #define LINUX_DIRBLKSIZ 512 static int getdents_common(struct thread *td, struct linux_getdents64_args *args, int is64bit) { struct dirent *bdp; struct vnode *vp; caddr_t inp, buf; /* BSD-format */ int len, reclen; /* BSD-format */ caddr_t outp; /* Linux-format */ int resid, linuxreclen=0; /* Linux-format */ caddr_t lbuf; /* Linux-format */ struct file *fp; struct uio auio; struct iovec aiov; off_t off; struct l_dirent *linux_dirent; struct l_dirent64 *linux_dirent64; int buflen, error, eofflag, nbytes, justone; u_long *cookies = NULL, *cookiep; int ncookies, vfslocked; nbytes = args->count; if (nbytes == 1) { /* readdir(2) case. Always struct dirent. */ if (is64bit) return (EINVAL); nbytes = sizeof(*linux_dirent); justone = 1; } else justone = 0; if ((error = getvnode(td->td_proc->p_fd, args->fd, CAP_READ, &fp)) != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); return (EBADF); } vp = fp->f_vnode; vfslocked = VFS_LOCK_GIANT(vp->v_mount); if (vp->v_type != VDIR) { VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (EINVAL); } off = fp->f_offset; buflen = max(LINUX_DIRBLKSIZ, nbytes); buflen = min(buflen, MAXBSIZE); buf = malloc(buflen, M_TEMP, M_WAITOK); lbuf = malloc(LINUX_MAXRECLEN, M_TEMP, M_WAITOK | M_ZERO); vn_lock(vp, LK_SHARED | LK_RETRY); aiov.iov_base = buf; aiov.iov_len = buflen; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_rw = UIO_READ; auio.uio_segflg = UIO_SYSSPACE; auio.uio_td = td; auio.uio_resid = buflen; auio.uio_offset = off; if (cookies) { free(cookies, M_TEMP); cookies = NULL; } #ifdef MAC /* * Do directory search MAC check using non-cached credentials. */ if ((error = mac_vnode_check_readdir(td->td_ucred, vp))) goto out; #endif /* MAC */ if ((error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies))) goto out; inp = buf; outp = (caddr_t)args->dirent; resid = nbytes; if ((len = buflen - auio.uio_resid) <= 0) goto eof; cookiep = cookies; if (cookies) { /* * When using cookies, the vfs has the option of reading from * a different offset than that supplied (UFS truncates the * offset to a block boundary to make sure that it never reads * partway through a directory entry, even if the directory * has been compacted). */ while (len > 0 && ncookies > 0 && *cookiep <= off) { bdp = (struct dirent *) inp; len -= bdp->d_reclen; inp += bdp->d_reclen; cookiep++; ncookies--; } } while (len > 0) { if (cookiep && ncookies == 0) break; bdp = (struct dirent *) inp; reclen = bdp->d_reclen; if (reclen & 3) { error = EFAULT; goto out; } if (bdp->d_fileno == 0) { inp += reclen; if (cookiep) { off = *cookiep++; ncookies--; } else off += reclen; len -= reclen; continue; } linuxreclen = (is64bit) ? LINUX_RECLEN64(bdp->d_namlen) : LINUX_RECLEN(bdp->d_namlen); if (reclen > len || resid < linuxreclen) { outp++; break; } if (justone) { /* readdir(2) case. */ linux_dirent = (struct l_dirent*)lbuf; linux_dirent->d_ino = bdp->d_fileno; linux_dirent->d_off = (l_off_t)linuxreclen; linux_dirent->d_reclen = (l_ushort)bdp->d_namlen; strlcpy(linux_dirent->d_name, bdp->d_name, linuxreclen - offsetof(struct l_dirent, d_name)); error = copyout(linux_dirent, outp, linuxreclen); } if (is64bit) { linux_dirent64 = (struct l_dirent64*)lbuf; linux_dirent64->d_ino = bdp->d_fileno; linux_dirent64->d_off = (cookiep) ? (l_off_t)*cookiep : (l_off_t)(off + reclen); linux_dirent64->d_reclen = (l_ushort)linuxreclen; linux_dirent64->d_type = bdp->d_type; strlcpy(linux_dirent64->d_name, bdp->d_name, linuxreclen - offsetof(struct l_dirent64, d_name)); error = copyout(linux_dirent64, outp, linuxreclen); } else if (!justone) { linux_dirent = (struct l_dirent*)lbuf; linux_dirent->d_ino = bdp->d_fileno; linux_dirent->d_off = (cookiep) ? (l_off_t)*cookiep : (l_off_t)(off + reclen); linux_dirent->d_reclen = (l_ushort)linuxreclen; /* * Copy d_type to last byte of l_dirent buffer */ lbuf[linuxreclen-1] = bdp->d_type; strlcpy(linux_dirent->d_name, bdp->d_name, linuxreclen - offsetof(struct l_dirent, d_name)-1); error = copyout(linux_dirent, outp, linuxreclen); } if (error) goto out; inp += reclen; if (cookiep) { off = *cookiep++; ncookies--; } else off += reclen; outp += linuxreclen; resid -= linuxreclen; len -= reclen; if (justone) break; } if (outp == (caddr_t)args->dirent) { nbytes = resid; goto eof; } fp->f_offset = off; if (justone) nbytes = resid + linuxreclen; eof: td->td_retval[0] = nbytes - resid; out: if (cookies) free(cookies, M_TEMP); VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); free(buf, M_TEMP); free(lbuf, M_TEMP); return (error); } int linux_getdents(struct thread *td, struct linux_getdents_args *args) { #ifdef DEBUG if (ldebug(getdents)) printf(ARGS(getdents, "%d, *, %d"), args->fd, args->count); #endif return (getdents_common(td, (struct linux_getdents64_args*)args, 0)); } int linux_getdents64(struct thread *td, struct linux_getdents64_args *args) { #ifdef DEBUG if (ldebug(getdents64)) printf(ARGS(getdents64, "%d, *, %d"), args->fd, args->count); #endif return (getdents_common(td, args, 1)); } /* * These exist mainly for hooks for doing /compat/linux translation. */ int linux_access(struct thread *td, struct linux_access_args *args) { char *path; int error; /* linux convention */ - if (args->flags & ~(F_OK | X_OK | W_OK | R_OK)) + if (args->amode & ~(F_OK | X_OK | W_OK | R_OK)) return (EINVAL); LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(access)) - printf(ARGS(access, "%s, %d"), path, args->flags); + printf(ARGS(access, "%s, %d"), path, args->amode); #endif - error = kern_access(td, path, UIO_SYSSPACE, args->flags); + error = kern_access(td, path, UIO_SYSSPACE, args->amode); LFREEPATH(path); return (error); } int linux_faccessat(struct thread *td, struct linux_faccessat_args *args) { char *path; int error, dfd; /* linux convention */ - if (args->mode & ~(F_OK | X_OK | W_OK | R_OK)) + if (args->amode & ~(F_OK | X_OK | W_OK | R_OK)) return (EINVAL); dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; LCONVPATHEXIST_AT(td, args->filename, &path, dfd); #ifdef DEBUG if (ldebug(access)) - printf(ARGS(access, "%s, %d"), path, args->mode); + printf(ARGS(access, "%s, %d"), path, args->amode); #endif error = kern_accessat(td, dfd, path, UIO_SYSSPACE, 0 /* XXX */, - args->mode); + args->amode); LFREEPATH(path); return (error); } int linux_unlink(struct thread *td, struct linux_unlink_args *args) { char *path; int error; struct stat st; LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(unlink)) printf(ARGS(unlink, "%s"), path); #endif error = kern_unlink(td, path, UIO_SYSSPACE); if (error == EPERM) /* Introduce POSIX noncompliant behaviour of Linux */ if (kern_stat(td, path, UIO_SYSSPACE, &st) == 0) if (S_ISDIR(st.st_mode)) error = EISDIR; LFREEPATH(path); return (error); } int linux_unlinkat(struct thread *td, struct linux_unlinkat_args *args) { char *path; int error, dfd; struct stat st; if (args->flag & ~LINUX_AT_REMOVEDIR) return (EINVAL); dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; LCONVPATHEXIST_AT(td, args->pathname, &path, dfd); #ifdef DEBUG if (ldebug(unlinkat)) printf(ARGS(unlinkat, "%s"), path); #endif if (args->flag & LINUX_AT_REMOVEDIR) error = kern_rmdirat(td, dfd, path, UIO_SYSSPACE); else error = kern_unlinkat(td, dfd, path, UIO_SYSSPACE, 0); if (error == EPERM && !(args->flag & LINUX_AT_REMOVEDIR)) { /* Introduce POSIX noncompliant behaviour of Linux */ if (kern_statat(td, AT_SYMLINK_NOFOLLOW, dfd, path, UIO_SYSSPACE, &st) == 0 && S_ISDIR(st.st_mode)) error = EISDIR; } LFREEPATH(path); return (error); } int linux_chdir(struct thread *td, struct linux_chdir_args *args) { char *path; int error; LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(chdir)) printf(ARGS(chdir, "%s"), path); #endif error = kern_chdir(td, path, UIO_SYSSPACE); LFREEPATH(path); return (error); } int linux_chmod(struct thread *td, struct linux_chmod_args *args) { char *path; int error; LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(chmod)) printf(ARGS(chmod, "%s, %d"), path, args->mode); #endif error = kern_chmod(td, path, UIO_SYSSPACE, args->mode); LFREEPATH(path); return (error); } int linux_fchmodat(struct thread *td, struct linux_fchmodat_args *args) { char *path; int error, dfd; dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; LCONVPATHEXIST_AT(td, args->filename, &path, dfd); #ifdef DEBUG if (ldebug(fchmodat)) printf(ARGS(fchmodat, "%s, %d"), path, args->mode); #endif error = kern_fchmodat(td, dfd, path, UIO_SYSSPACE, args->mode, 0); LFREEPATH(path); return (error); } int linux_mkdir(struct thread *td, struct linux_mkdir_args *args) { char *path; int error; LCONVPATHCREAT(td, args->path, &path); #ifdef DEBUG if (ldebug(mkdir)) printf(ARGS(mkdir, "%s, %d"), path, args->mode); #endif error = kern_mkdir(td, path, UIO_SYSSPACE, args->mode); LFREEPATH(path); return (error); } int linux_mkdirat(struct thread *td, struct linux_mkdirat_args *args) { char *path; int error, dfd; dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; LCONVPATHCREAT_AT(td, args->pathname, &path, dfd); #ifdef DEBUG if (ldebug(mkdirat)) printf(ARGS(mkdirat, "%s, %d"), path, args->mode); #endif error = kern_mkdirat(td, dfd, path, UIO_SYSSPACE, args->mode); LFREEPATH(path); return (error); } int linux_rmdir(struct thread *td, struct linux_rmdir_args *args) { char *path; int error; LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(rmdir)) printf(ARGS(rmdir, "%s"), path); #endif error = kern_rmdir(td, path, UIO_SYSSPACE); LFREEPATH(path); return (error); } int linux_rename(struct thread *td, struct linux_rename_args *args) { char *from, *to; int error; LCONVPATHEXIST(td, args->from, &from); /* Expand LCONVPATHCREATE so that `from' can be freed on errors */ error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); if (to == NULL) { LFREEPATH(from); return (error); } #ifdef DEBUG if (ldebug(rename)) printf(ARGS(rename, "%s, %s"), from, to); #endif error = kern_rename(td, from, to, UIO_SYSSPACE); LFREEPATH(from); LFREEPATH(to); return (error); } int linux_renameat(struct thread *td, struct linux_renameat_args *args) { char *from, *to; int error, olddfd, newdfd; olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd; newdfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd; LCONVPATHEXIST_AT(td, args->oldname, &from, olddfd); /* Expand LCONVPATHCREATE so that `from' can be freed on errors */ error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd); if (to == NULL) { LFREEPATH(from); return (error); } #ifdef DEBUG if (ldebug(renameat)) printf(ARGS(renameat, "%s, %s"), from, to); #endif error = kern_renameat(td, olddfd, from, newdfd, to, UIO_SYSSPACE); LFREEPATH(from); LFREEPATH(to); return (error); } int linux_symlink(struct thread *td, struct linux_symlink_args *args) { char *path, *to; int error; LCONVPATHEXIST(td, args->path, &path); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); if (to == NULL) { LFREEPATH(path); return (error); } #ifdef DEBUG if (ldebug(symlink)) printf(ARGS(symlink, "%s, %s"), path, to); #endif error = kern_symlink(td, path, to, UIO_SYSSPACE); LFREEPATH(path); LFREEPATH(to); return (error); } int linux_symlinkat(struct thread *td, struct linux_symlinkat_args *args) { char *path, *to; int error, dfd; dfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd; LCONVPATHEXIST_AT(td, args->oldname, &path, dfd); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, dfd); if (to == NULL) { LFREEPATH(path); return (error); } #ifdef DEBUG if (ldebug(symlinkat)) printf(ARGS(symlinkat, "%s, %s"), path, to); #endif error = kern_symlinkat(td, path, dfd, to, UIO_SYSSPACE); LFREEPATH(path); LFREEPATH(to); return (error); } int linux_readlink(struct thread *td, struct linux_readlink_args *args) { char *name; int error; LCONVPATHEXIST(td, args->name, &name); #ifdef DEBUG if (ldebug(readlink)) printf(ARGS(readlink, "%s, %p, %d"), name, (void *)args->buf, args->count); #endif error = kern_readlink(td, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE, args->count); LFREEPATH(name); return (error); } int linux_readlinkat(struct thread *td, struct linux_readlinkat_args *args) { char *name; int error, dfd; dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; LCONVPATHEXIST_AT(td, args->path, &name, dfd); #ifdef DEBUG if (ldebug(readlinkat)) printf(ARGS(readlinkat, "%s, %p, %d"), name, (void *)args->buf, args->bufsiz); #endif error = kern_readlinkat(td, dfd, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE, args->bufsiz); LFREEPATH(name); return (error); } int linux_truncate(struct thread *td, struct linux_truncate_args *args) { char *path; int error; LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(truncate)) printf(ARGS(truncate, "%s, %ld"), path, (long)args->length); #endif error = kern_truncate(td, path, UIO_SYSSPACE, args->length); LFREEPATH(path); return (error); } int linux_truncate64(struct thread *td, struct linux_truncate64_args *args) { char *path; int error; LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(truncate64)) printf(ARGS(truncate64, "%s, %jd"), path, args->length); #endif error = kern_truncate(td, path, UIO_SYSSPACE, args->length); LFREEPATH(path); return (error); } int linux_ftruncate(struct thread *td, struct linux_ftruncate_args *args) { struct ftruncate_args /* { int fd; int pad; off_t length; } */ nuap; nuap.fd = args->fd; nuap.length = args->length; return (sys_ftruncate(td, &nuap)); } int linux_link(struct thread *td, struct linux_link_args *args) { char *path, *to; int error; LCONVPATHEXIST(td, args->path, &path); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); if (to == NULL) { LFREEPATH(path); return (error); } #ifdef DEBUG if (ldebug(link)) printf(ARGS(link, "%s, %s"), path, to); #endif error = kern_link(td, path, to, UIO_SYSSPACE); LFREEPATH(path); LFREEPATH(to); return (error); } int linux_linkat(struct thread *td, struct linux_linkat_args *args) { char *path, *to; int error, olddfd, newdfd; /* * They really introduced flags argument which is forbidden to * use. */ if (args->flags != 0) return (EINVAL); olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd; newdfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd; LCONVPATHEXIST_AT(td, args->oldname, &path, olddfd); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd); if (to == NULL) { LFREEPATH(path); return (error); } #ifdef DEBUG if (ldebug(linkat)) printf(ARGS(linkat, "%i, %s, %i, %s, %i"), args->olddfd, path, args->newdfd, to, args->flags); #endif error = kern_linkat(td, olddfd, newdfd, path, to, UIO_SYSSPACE, FOLLOW); LFREEPATH(path); LFREEPATH(to); return (error); } int linux_fdatasync(td, uap) struct thread *td; struct linux_fdatasync_args *uap; { struct fsync_args bsd; bsd.fd = uap->fd; return sys_fsync(td, &bsd); } int linux_pread(td, uap) struct thread *td; struct linux_pread_args *uap; { struct pread_args bsd; struct vnode *vp; int error; bsd.fd = uap->fd; bsd.buf = uap->buf; bsd.nbyte = uap->nbyte; bsd.offset = uap->offset; error = sys_pread(td, &bsd); if (error == 0) { /* This seems to violate POSIX but linux does it */ if ((error = fgetvp(td, uap->fd, CAP_READ, &vp)) != 0) return (error); if (vp->v_type == VDIR) { vrele(vp); return (EISDIR); } vrele(vp); } return (error); } int linux_pwrite(td, uap) struct thread *td; struct linux_pwrite_args *uap; { struct pwrite_args bsd; bsd.fd = uap->fd; bsd.buf = uap->buf; bsd.nbyte = uap->nbyte; bsd.offset = uap->offset; return sys_pwrite(td, &bsd); } int linux_mount(struct thread *td, struct linux_mount_args *args) { struct ufs_args ufs; char fstypename[MFSNAMELEN]; char mntonname[MNAMELEN], mntfromname[MNAMELEN]; int error; int fsflags; void *fsdata; error = copyinstr(args->filesystemtype, fstypename, MFSNAMELEN - 1, NULL); if (error) return (error); error = copyinstr(args->specialfile, mntfromname, MNAMELEN - 1, NULL); if (error) return (error); error = copyinstr(args->dir, mntonname, MNAMELEN - 1, NULL); if (error) return (error); #ifdef DEBUG if (ldebug(mount)) printf(ARGS(mount, "%s, %s, %s"), fstypename, mntfromname, mntonname); #endif if (strcmp(fstypename, "ext2") == 0) { strcpy(fstypename, "ext2fs"); fsdata = &ufs; ufs.fspec = mntfromname; #define DEFAULT_ROOTID -2 ufs.export.ex_root = DEFAULT_ROOTID; ufs.export.ex_flags = args->rwflag & LINUX_MS_RDONLY ? MNT_EXRDONLY : 0; } else if (strcmp(fstypename, "proc") == 0) { strcpy(fstypename, "linprocfs"); fsdata = NULL; } else if (strcmp(fstypename, "vfat") == 0) { strcpy(fstypename, "msdosfs"); fsdata = NULL; } else { return (ENODEV); } fsflags = 0; if ((args->rwflag & 0xffff0000) == 0xc0ed0000) { /* * Linux SYNC flag is not included; the closest equivalent * FreeBSD has is !ASYNC, which is our default. */ if (args->rwflag & LINUX_MS_RDONLY) fsflags |= MNT_RDONLY; if (args->rwflag & LINUX_MS_NOSUID) fsflags |= MNT_NOSUID; if (args->rwflag & LINUX_MS_NOEXEC) fsflags |= MNT_NOEXEC; if (args->rwflag & LINUX_MS_REMOUNT) fsflags |= MNT_UPDATE; } if (strcmp(fstypename, "linprocfs") == 0) { error = kernel_vmount(fsflags, "fstype", fstypename, "fspath", mntonname, NULL); } else if (strcmp(fstypename, "msdosfs") == 0) { error = kernel_vmount(fsflags, "fstype", fstypename, "fspath", mntonname, "from", mntfromname, NULL); } else error = EOPNOTSUPP; return (error); } int linux_oldumount(struct thread *td, struct linux_oldumount_args *args) { struct linux_umount_args args2; args2.path = args->path; args2.flags = 0; return (linux_umount(td, &args2)); } int linux_umount(struct thread *td, struct linux_umount_args *args) { struct unmount_args bsd; bsd.path = args->path; bsd.flags = args->flags; /* XXX correct? */ return (sys_unmount(td, &bsd)); } /* * fcntl family of syscalls */ struct l_flock { l_short l_type; l_short l_whence; l_off_t l_start; l_off_t l_len; l_pid_t l_pid; } #if defined(__amd64__) && defined(COMPAT_LINUX32) __packed #endif ; static void linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock) { switch (linux_flock->l_type) { case LINUX_F_RDLCK: bsd_flock->l_type = F_RDLCK; break; case LINUX_F_WRLCK: bsd_flock->l_type = F_WRLCK; break; case LINUX_F_UNLCK: bsd_flock->l_type = F_UNLCK; break; default: bsd_flock->l_type = -1; break; } bsd_flock->l_whence = linux_flock->l_whence; bsd_flock->l_start = (off_t)linux_flock->l_start; bsd_flock->l_len = (off_t)linux_flock->l_len; bsd_flock->l_pid = (pid_t)linux_flock->l_pid; bsd_flock->l_sysid = 0; } static void bsd_to_linux_flock(struct flock *bsd_flock, struct l_flock *linux_flock) { switch (bsd_flock->l_type) { case F_RDLCK: linux_flock->l_type = LINUX_F_RDLCK; break; case F_WRLCK: linux_flock->l_type = LINUX_F_WRLCK; break; case F_UNLCK: linux_flock->l_type = LINUX_F_UNLCK; break; } linux_flock->l_whence = bsd_flock->l_whence; linux_flock->l_start = (l_off_t)bsd_flock->l_start; linux_flock->l_len = (l_off_t)bsd_flock->l_len; linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid; } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) struct l_flock64 { l_short l_type; l_short l_whence; l_loff_t l_start; l_loff_t l_len; l_pid_t l_pid; } #if defined(__amd64__) && defined(COMPAT_LINUX32) __packed #endif ; static void linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock) { switch (linux_flock->l_type) { case LINUX_F_RDLCK: bsd_flock->l_type = F_RDLCK; break; case LINUX_F_WRLCK: bsd_flock->l_type = F_WRLCK; break; case LINUX_F_UNLCK: bsd_flock->l_type = F_UNLCK; break; default: bsd_flock->l_type = -1; break; } bsd_flock->l_whence = linux_flock->l_whence; bsd_flock->l_start = (off_t)linux_flock->l_start; bsd_flock->l_len = (off_t)linux_flock->l_len; bsd_flock->l_pid = (pid_t)linux_flock->l_pid; bsd_flock->l_sysid = 0; } static void bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock) { switch (bsd_flock->l_type) { case F_RDLCK: linux_flock->l_type = LINUX_F_RDLCK; break; case F_WRLCK: linux_flock->l_type = LINUX_F_WRLCK; break; case F_UNLCK: linux_flock->l_type = LINUX_F_UNLCK; break; } linux_flock->l_whence = bsd_flock->l_whence; linux_flock->l_start = (l_loff_t)bsd_flock->l_start; linux_flock->l_len = (l_loff_t)bsd_flock->l_len; linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid; } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ static int fcntl_common(struct thread *td, struct linux_fcntl64_args *args) { struct l_flock linux_flock; struct flock bsd_flock; struct file *fp; long arg; int error, result; switch (args->cmd) { case LINUX_F_DUPFD: return (kern_fcntl(td, args->fd, F_DUPFD, args->arg)); case LINUX_F_GETFD: return (kern_fcntl(td, args->fd, F_GETFD, 0)); case LINUX_F_SETFD: return (kern_fcntl(td, args->fd, F_SETFD, args->arg)); case LINUX_F_GETFL: error = kern_fcntl(td, args->fd, F_GETFL, 0); result = td->td_retval[0]; td->td_retval[0] = 0; if (result & O_RDONLY) td->td_retval[0] |= LINUX_O_RDONLY; if (result & O_WRONLY) td->td_retval[0] |= LINUX_O_WRONLY; if (result & O_RDWR) td->td_retval[0] |= LINUX_O_RDWR; if (result & O_NDELAY) td->td_retval[0] |= LINUX_O_NONBLOCK; if (result & O_APPEND) td->td_retval[0] |= LINUX_O_APPEND; if (result & O_FSYNC) td->td_retval[0] |= LINUX_O_SYNC; if (result & O_ASYNC) td->td_retval[0] |= LINUX_FASYNC; #ifdef LINUX_O_NOFOLLOW if (result & O_NOFOLLOW) td->td_retval[0] |= LINUX_O_NOFOLLOW; #endif #ifdef LINUX_O_DIRECT if (result & O_DIRECT) td->td_retval[0] |= LINUX_O_DIRECT; #endif return (error); case LINUX_F_SETFL: arg = 0; if (args->arg & LINUX_O_NDELAY) arg |= O_NONBLOCK; if (args->arg & LINUX_O_APPEND) arg |= O_APPEND; if (args->arg & LINUX_O_SYNC) arg |= O_FSYNC; if (args->arg & LINUX_FASYNC) arg |= O_ASYNC; #ifdef LINUX_O_NOFOLLOW if (args->arg & LINUX_O_NOFOLLOW) arg |= O_NOFOLLOW; #endif #ifdef LINUX_O_DIRECT if (args->arg & LINUX_O_DIRECT) arg |= O_DIRECT; #endif return (kern_fcntl(td, args->fd, F_SETFL, arg)); case LINUX_F_GETLK: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock(&linux_flock, &bsd_flock); error = kern_fcntl(td, args->fd, F_GETLK, (intptr_t)&bsd_flock); if (error) return (error); bsd_to_linux_flock(&bsd_flock, &linux_flock); return (copyout(&linux_flock, (void *)args->arg, sizeof(linux_flock))); case LINUX_F_SETLK: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock(&linux_flock, &bsd_flock); return (kern_fcntl(td, args->fd, F_SETLK, (intptr_t)&bsd_flock)); case LINUX_F_SETLKW: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock(&linux_flock, &bsd_flock); return (kern_fcntl(td, args->fd, F_SETLKW, (intptr_t)&bsd_flock)); case LINUX_F_GETOWN: return (kern_fcntl(td, args->fd, F_GETOWN, 0)); case LINUX_F_SETOWN: /* * XXX some Linux applications depend on F_SETOWN having no * significant effect for pipes (SIGIO is not delivered for * pipes under Linux-2.2.35 at least). */ error = fget(td, args->fd, CAP_FCNTL, &fp); if (error) return (error); if (fp->f_type == DTYPE_PIPE) { fdrop(fp, td); return (EINVAL); } fdrop(fp, td); return (kern_fcntl(td, args->fd, F_SETOWN, args->arg)); } return (EINVAL); } int linux_fcntl(struct thread *td, struct linux_fcntl_args *args) { struct linux_fcntl64_args args64; #ifdef DEBUG if (ldebug(fcntl)) printf(ARGS(fcntl, "%d, %08x, *"), args->fd, args->cmd); #endif args64.fd = args->fd; args64.cmd = args->cmd; args64.arg = args->arg; return (fcntl_common(td, &args64)); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_fcntl64(struct thread *td, struct linux_fcntl64_args *args) { struct l_flock64 linux_flock; struct flock bsd_flock; int error; #ifdef DEBUG if (ldebug(fcntl64)) printf(ARGS(fcntl64, "%d, %08x, *"), args->fd, args->cmd); #endif switch (args->cmd) { case LINUX_F_GETLK64: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock64(&linux_flock, &bsd_flock); error = kern_fcntl(td, args->fd, F_GETLK, (intptr_t)&bsd_flock); if (error) return (error); bsd_to_linux_flock64(&bsd_flock, &linux_flock); return (copyout(&linux_flock, (void *)args->arg, sizeof(linux_flock))); case LINUX_F_SETLK64: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock64(&linux_flock, &bsd_flock); return (kern_fcntl(td, args->fd, F_SETLK, (intptr_t)&bsd_flock)); case LINUX_F_SETLKW64: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock64(&linux_flock, &bsd_flock); return (kern_fcntl(td, args->fd, F_SETLKW, (intptr_t)&bsd_flock)); } return (fcntl_common(td, args)); } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_chown(struct thread *td, struct linux_chown_args *args) { char *path; int error; LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(chown)) printf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid); #endif error = kern_chown(td, path, UIO_SYSSPACE, args->uid, args->gid); LFREEPATH(path); return (error); } int linux_fchownat(struct thread *td, struct linux_fchownat_args *args) { char *path; int error, dfd, follow; if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW) return (EINVAL); dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; LCONVPATHEXIST_AT(td, args->filename, &path, dfd); #ifdef DEBUG if (ldebug(fchownat)) printf(ARGS(fchownat, "%s, %d, %d"), path, args->uid, args->gid); #endif follow = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) == 0 ? 0 : AT_SYMLINK_NOFOLLOW; error = kern_fchownat(td, dfd, path, UIO_SYSSPACE, args->uid, args->gid, follow); LFREEPATH(path); return (error); } int linux_lchown(struct thread *td, struct linux_lchown_args *args) { char *path; int error; LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(lchown)) printf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid); #endif error = kern_lchown(td, path, UIO_SYSSPACE, args->uid, args->gid); LFREEPATH(path); return (error); } diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c index cbca7e24b1fb..b9d3ace3ef1f 100644 --- a/sys/compat/svr4/svr4_fcntl.c +++ b/sys/compat/svr4/svr4_fcntl.c @@ -1,724 +1,724 @@ /*- * Copyright (c) 1998 Mark Newton * Copyright (c) 1994, 1997 Christos Zoulas. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christos Zoulas. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include /*#include */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int svr4_to_bsd_flags(int); static u_long svr4_to_bsd_cmd(u_long); static int fd_revoke(struct thread *, int); static int fd_truncate(struct thread *, int, struct flock *); static int bsd_to_svr4_flags(int); static void bsd_to_svr4_flock(struct flock *, struct svr4_flock *); static void svr4_to_bsd_flock(struct svr4_flock *, struct flock *); static void bsd_to_svr4_flock64(struct flock *, struct svr4_flock64 *); static void svr4_to_bsd_flock64(struct svr4_flock64 *, struct flock *); static u_long svr4_to_bsd_cmd(cmd) u_long cmd; { switch (cmd) { case SVR4_F_DUPFD: return F_DUPFD; case SVR4_F_DUP2FD: return F_DUP2FD; case SVR4_F_GETFD: return F_GETFD; case SVR4_F_SETFD: return F_SETFD; case SVR4_F_GETFL: return F_GETFL; case SVR4_F_SETFL: return F_SETFL; case SVR4_F_GETLK: return F_GETLK; case SVR4_F_SETLK: return F_SETLK; case SVR4_F_SETLKW: return F_SETLKW; default: return -1; } } static int svr4_to_bsd_flags(l) int l; { int r = 0; r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0; r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0; r |= (l & SVR4_O_RDWR) ? O_RDWR : 0; r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0; r |= (l & SVR4_O_APPEND) ? O_APPEND : 0; r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0; r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0; r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0; r |= (l & SVR4_O_CREAT) ? O_CREAT : 0; r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0; r |= (l & SVR4_O_EXCL) ? O_EXCL : 0; r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0; return r; } static int bsd_to_svr4_flags(l) int l; { int r = 0; r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0; r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0; r |= (l & O_RDWR) ? SVR4_O_RDWR : 0; r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0; r |= (l & O_APPEND) ? SVR4_O_APPEND : 0; r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0; r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0; r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0; r |= (l & O_CREAT) ? SVR4_O_CREAT : 0; r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0; r |= (l & O_EXCL) ? SVR4_O_EXCL : 0; r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0; return r; } static void bsd_to_svr4_flock(iflp, oflp) struct flock *iflp; struct svr4_flock *oflp; { switch (iflp->l_type) { case F_RDLCK: oflp->l_type = SVR4_F_RDLCK; break; case F_WRLCK: oflp->l_type = SVR4_F_WRLCK; break; case F_UNLCK: oflp->l_type = SVR4_F_UNLCK; break; default: oflp->l_type = -1; break; } oflp->l_whence = (short) iflp->l_whence; oflp->l_start = (svr4_off_t) iflp->l_start; oflp->l_len = (svr4_off_t) iflp->l_len; oflp->l_sysid = 0; oflp->l_pid = (svr4_pid_t) iflp->l_pid; } static void svr4_to_bsd_flock(iflp, oflp) struct svr4_flock *iflp; struct flock *oflp; { switch (iflp->l_type) { case SVR4_F_RDLCK: oflp->l_type = F_RDLCK; break; case SVR4_F_WRLCK: oflp->l_type = F_WRLCK; break; case SVR4_F_UNLCK: oflp->l_type = F_UNLCK; break; default: oflp->l_type = -1; break; } oflp->l_whence = iflp->l_whence; oflp->l_start = (off_t) iflp->l_start; oflp->l_len = (off_t) iflp->l_len; oflp->l_pid = (pid_t) iflp->l_pid; oflp->l_sysid = iflp->l_sysid; } static void bsd_to_svr4_flock64(iflp, oflp) struct flock *iflp; struct svr4_flock64 *oflp; { switch (iflp->l_type) { case F_RDLCK: oflp->l_type = SVR4_F_RDLCK; break; case F_WRLCK: oflp->l_type = SVR4_F_WRLCK; break; case F_UNLCK: oflp->l_type = SVR4_F_UNLCK; break; default: oflp->l_type = -1; break; } oflp->l_whence = (short) iflp->l_whence; oflp->l_start = (svr4_off64_t) iflp->l_start; oflp->l_len = (svr4_off64_t) iflp->l_len; oflp->l_sysid = iflp->l_sysid; oflp->l_pid = (svr4_pid_t) iflp->l_pid; } static void svr4_to_bsd_flock64(iflp, oflp) struct svr4_flock64 *iflp; struct flock *oflp; { switch (iflp->l_type) { case SVR4_F_RDLCK: oflp->l_type = F_RDLCK; break; case SVR4_F_WRLCK: oflp->l_type = F_WRLCK; break; case SVR4_F_UNLCK: oflp->l_type = F_UNLCK; break; default: oflp->l_type = -1; break; } oflp->l_whence = iflp->l_whence; oflp->l_start = (off_t) iflp->l_start; oflp->l_len = (off_t) iflp->l_len; oflp->l_pid = (pid_t) iflp->l_pid; } static int fd_revoke(td, fd) struct thread *td; int fd; { struct vnode *vp; struct mount *mp; struct vattr vattr; int error, *retval; retval = td->td_retval; /* * If we ever want to support Capsicum on SVR4 processes (unlikely) * or FreeBSD grows a native frevoke() (more likely), we will need a * CAP_REVOKE here. * * In the meantime, use CAP_MASK_VALID: if a SVR4 process wants to * do an frevoke(), it needs to do it on either a regular file * descriptor or a fully-privileged capability (which is effectively * the same as a non-capability-restricted file descriptor). */ if ((error = fgetvp(td, fd, CAP_MASK_VALID, &vp)) != 0) return (error); if (vp->v_type != VCHR && vp->v_type != VBLK) { error = EINVAL; goto out; } #ifdef MAC vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); error = mac_vnode_check_revoke(td->td_ucred, vp); VOP_UNLOCK(vp, 0); if (error) goto out; #endif if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred)) != 0) goto out; if (td->td_ucred->cr_uid != vattr.va_uid && (error = priv_check(td, PRIV_VFS_ADMIN)) != 0) goto out; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) goto out; if (vcount(vp) > 1) VOP_REVOKE(vp, REVOKEALL); vn_finished_write(mp); out: vrele(vp); return error; } static int fd_truncate(td, fd, flp) struct thread *td; int fd; struct flock *flp; { off_t start, length; struct file *fp; struct vnode *vp; struct vattr vattr; int error, *retval; struct ftruncate_args ft; retval = td->td_retval; /* * We only support truncating the file. */ if ((error = fget(td, fd, CAP_FTRUNCATE, &fp)) != 0) return (error); vp = fp->f_vnode; if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { fdrop(fp, td); return ESPIPE; } if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred)) != 0) { fdrop(fp, td); return error; } length = vattr.va_size; switch (flp->l_whence) { case SEEK_CUR: start = fp->f_offset + flp->l_start; break; case SEEK_END: start = flp->l_start + length; break; case SEEK_SET: start = flp->l_start; break; default: fdrop(fp, td); return EINVAL; } if (start + flp->l_len < length) { /* We don't support free'ing in the middle of the file */ fdrop(fp, td); return EINVAL; } ft.fd = fd; ft.length = start; error = sys_ftruncate(td, &ft); fdrop(fp, td); return (error); } int svr4_sys_open(td, uap) struct thread *td; struct svr4_sys_open_args *uap; { struct proc *p = td->td_proc; char *newpath; int bsd_flags, error, retval; CHECKALTEXIST(td, uap->path, &newpath); bsd_flags = svr4_to_bsd_flags(uap->flags); error = kern_open(td, newpath, UIO_SYSSPACE, bsd_flags, uap->mode); free(newpath, M_TEMP); if (error) { /* uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path, uap->flags, uap->mode, error);*/ return error; } retval = td->td_retval[0]; PROC_LOCK(p); if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { #if defined(NOTYET) struct file *fp; error = fget(td, retval, CAP_IOCTL, &fp); PROC_UNLOCK(p); /* * we may have lost a race the above open() and * another thread issuing a close() */ if (error) return (EBADF); /* XXX: correct errno? */ /* ignore any error, just give it a try */ if (fp->f_type == DTYPE_VNODE) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred, td); fdrop(fp, td); } else { PROC_UNLOCK(p); } #else } PROC_UNLOCK(p); #endif return error; } int svr4_sys_open64(td, uap) struct thread *td; struct svr4_sys_open64_args *uap; { return svr4_sys_open(td, (struct svr4_sys_open_args *)uap); } int svr4_sys_creat(td, uap) struct thread *td; struct svr4_sys_creat_args *uap; { char *newpath; int error; CHECKALTEXIST(td, uap->path, &newpath); error = kern_open(td, newpath, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC, uap->mode); free(newpath, M_TEMP); return (error); } int svr4_sys_creat64(td, uap) struct thread *td; struct svr4_sys_creat64_args *uap; { return svr4_sys_creat(td, (struct svr4_sys_creat_args *)uap); } int svr4_sys_llseek(td, uap) struct thread *td; struct svr4_sys_llseek_args *uap; { struct lseek_args ap; ap.fd = uap->fd; #if BYTE_ORDER == BIG_ENDIAN ap.offset = (((u_int64_t) uap->offset1) << 32) | uap->offset2; #else ap.offset = (((u_int64_t) uap->offset2) << 32) | uap->offset1; #endif ap.whence = uap->whence; return sys_lseek(td, &ap); } int svr4_sys_access(td, uap) struct thread *td; struct svr4_sys_access_args *uap; { char *newpath; int error; CHECKALTEXIST(td, uap->path, &newpath); - error = kern_access(td, newpath, UIO_SYSSPACE, uap->flags); + error = kern_access(td, newpath, UIO_SYSSPACE, uap->amode); free(newpath, M_TEMP); return (error); } #if defined(NOTYET) int svr4_sys_pread(td, uap) struct thread *td; struct svr4_sys_pread_args *uap; { struct pread_args pra; /* * Just translate the args structure and call the NetBSD * pread(2) system call (offset type is 64-bit in NetBSD). */ pra.fd = uap->fd; pra.buf = uap->buf; pra.nbyte = uap->nbyte; pra.offset = uap->off; return pread(td, &pra); } #endif #if defined(NOTYET) int svr4_sys_pread64(td, v, retval) struct thread *td; void *v; register_t *retval; { struct svr4_sys_pread64_args *uap = v; struct sys_pread_args pra; /* * Just translate the args structure and call the NetBSD * pread(2) system call (offset type is 64-bit in NetBSD). */ pra.fd = uap->fd; pra.buf = uap->buf; pra.nbyte = uap->nbyte; pra.offset = uap->off; return (sys_pread(td, &pra, retval)); } #endif /* NOTYET */ #if defined(NOTYET) int svr4_sys_pwrite(td, uap) struct thread *td; struct svr4_sys_pwrite_args *uap; { struct pwrite_args pwa; /* * Just translate the args structure and call the NetBSD * pwrite(2) system call (offset type is 64-bit in NetBSD). */ pwa.fd = uap->fd; pwa.buf = uap->buf; pwa.nbyte = uap->nbyte; pwa.offset = uap->off; return pwrite(td, &pwa); } #endif #if defined(NOTYET) int svr4_sys_pwrite64(td, v, retval) struct thread *td; void *v; register_t *retval; { struct svr4_sys_pwrite64_args *uap = v; struct sys_pwrite_args pwa; /* * Just translate the args structure and call the NetBSD * pwrite(2) system call (offset type is 64-bit in NetBSD). */ pwa.fd = uap->fd; pwa.buf = uap->buf; pwa.nbyte = uap->nbyte; pwa.offset = uap->off; return (sys_pwrite(td, &pwa, retval)); } #endif /* NOTYET */ int svr4_sys_fcntl(td, uap) struct thread *td; struct svr4_sys_fcntl_args *uap; { int cmd, error, *retval; retval = td->td_retval; cmd = svr4_to_bsd_cmd(uap->cmd); switch (cmd) { case F_DUPFD: case F_DUP2FD: case F_GETFD: case F_SETFD: return (kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg)); case F_GETFL: error = kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg); if (error) return (error); *retval = bsd_to_svr4_flags(*retval); return (error); case F_SETFL: { /* * we must save the O_ASYNC flag, as that is * handled by ioctl(_, I_SETSIG, _) emulation. */ int flags; DPRINTF(("Setting flags %p\n", uap->arg)); error = kern_fcntl(td, uap->fd, F_GETFL, 0); if (error) return (error); flags = *retval; flags &= O_ASYNC; flags |= svr4_to_bsd_flags((u_long) uap->arg); return (kern_fcntl(td, uap->fd, F_SETFL, flags)); } case F_GETLK: case F_SETLK: case F_SETLKW: { struct svr4_flock ifl; struct flock fl; error = copyin(uap->arg, &ifl, sizeof (ifl)); if (error) return (error); svr4_to_bsd_flock(&ifl, &fl); error = kern_fcntl(td, uap->fd, cmd, (intptr_t)&fl); if (error || cmd != F_GETLK) return (error); bsd_to_svr4_flock(&fl, &ifl); return (copyout(&ifl, uap->arg, sizeof (ifl))); } case -1: switch (uap->cmd) { case SVR4_F_FREESP: { struct svr4_flock ifl; struct flock fl; error = copyin(uap->arg, &ifl, sizeof ifl); if (error) return error; svr4_to_bsd_flock(&ifl, &fl); return fd_truncate(td, uap->fd, &fl); } case SVR4_F_GETLK64: case SVR4_F_SETLK64: case SVR4_F_SETLKW64: { struct svr4_flock64 ifl; struct flock fl; switch (uap->cmd) { case SVR4_F_GETLK64: cmd = F_GETLK; break; case SVR4_F_SETLK64: cmd = F_SETLK; break; case SVR4_F_SETLKW64: cmd = F_SETLKW; break; } error = copyin(uap->arg, &ifl, sizeof (ifl)); if (error) return (error); svr4_to_bsd_flock64(&ifl, &fl); error = kern_fcntl(td, uap->fd, cmd, (intptr_t)&fl); if (error || cmd != F_GETLK) return (error); bsd_to_svr4_flock64(&fl, &ifl); return (copyout(&ifl, uap->arg, sizeof (ifl))); } case SVR4_F_FREESP64: { struct svr4_flock64 ifl; struct flock fl; error = copyin(uap->arg, &ifl, sizeof ifl); if (error) return error; svr4_to_bsd_flock64(&ifl, &fl); return fd_truncate(td, uap->fd, &fl); } case SVR4_F_REVOKE: return fd_revoke(td, uap->fd); default: return ENOSYS; } default: return ENOSYS; } } diff --git a/sys/compat/svr4/syscalls.master b/sys/compat/svr4/syscalls.master index 2d6afee38a72..0997ab7f641e 100644 --- a/sys/compat/svr4/syscalls.master +++ b/sys/compat/svr4/syscalls.master @@ -1,396 +1,396 @@ $FreeBSD$ ; from: @(#)syscalls.master 8.1 (Berkeley) 7/19/93 ; ; System call name/number master file (or rather, slave, from SVR4). ; Processed to create svr4_sysent.c, svr4_syscalls.c and svr4_syscall.h. ; Columns: number type nargs name alt{name,tag,rtyp}/comments ; number system call number, must be in order ; audit the audit event associated with the system call ; A value of AUE_NULL means no auditing, but it also means that ; there is no audit event for the call at this time. For the ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, OBSOL, UNIMPL, COMPAT ; name psuedo-prototype of syscall routine ; If one of the following alts is different, then all appear: ; altname name of system call if different ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL/OBSOL, name continues with comments ; types: ; STD always included ; COMPAT included on COMPAT #ifdef ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only ; #ifdef's, etc. may be included, and are copied to the output files. #include #include #include #include #include #include #include #include 0 AUE_NULL UNIMPL unused 1 AUE_NULL NOPROTO { void sys_exit(int rval); } exit \ sys_exit_args void 2 AUE_NULL NOPROTO { int fork(void); } 3 AUE_NULL NOPROTO { int read(int fd, char *buf, u_int nbyte); } 4 AUE_NULL NOPROTO { int write(int fd, char *buf, u_int nbyte); } 5 AUE_NULL STD { int svr4_sys_open(char *path, int flags, \ int mode); } 6 AUE_NULL NOPROTO { int close(int fd); } 7 AUE_NULL STD { int svr4_sys_wait(int *status); } 8 AUE_NULL STD { int svr4_sys_creat(char *path, int mode); } 9 AUE_NULL NOPROTO { int link(char *path, char *link); } 10 AUE_NULL NOPROTO { int unlink(char *path); } 11 AUE_NULL STD { int svr4_sys_execv(char *path, char **argp); } 12 AUE_NULL NOPROTO { int chdir(char *path); } 13 AUE_NULL STD { int svr4_sys_time(time_t *t); } 14 AUE_NULL STD { int svr4_sys_mknod(char* path, int mode, int dev); } 15 AUE_NULL NOPROTO { int chmod(char *path, int mode); } 16 AUE_NULL NOPROTO { int chown(char *path, uid_t uid, gid_t gid); } 17 AUE_NULL STD { int svr4_sys_break(caddr_t nsize); } 18 AUE_NULL STD { int svr4_sys_stat(char* path, \ struct svr4_stat* ub); } 19 AUE_NULL NOPROTO { int lseek(int filedes, off_t *offset, \ int whence); } 20 AUE_NULL NOPROTO { pid_t getpid(void); } 21 AUE_NULL UNIMPL old_mount 22 AUE_NULL UNIMPL sysv_umount 23 AUE_NULL NOPROTO { int setuid(uid_t uid); } 24 AUE_NULL NOPROTO { uid_t getuid(void); } 25 AUE_NULL UNIMPL stime 26 AUE_NULL UNIMPL ptrace 27 AUE_NULL STD { int svr4_sys_alarm(unsigned sec); } 28 AUE_NULL STD { int svr4_sys_fstat(int fd, \ struct svr4_stat *sb); } 29 AUE_NULL STD { int svr4_sys_pause(void); } 30 AUE_NULL STD { int svr4_sys_utime(char *path, \ struct svr4_utimbuf *ubuf); } 31 AUE_NULL UNIMPL stty 32 AUE_NULL UNIMPL gtty 33 AUE_NULL STD { int svr4_sys_access(char *path, \ - int flags); } + int amode); } 34 AUE_NULL STD { int svr4_sys_nice(int prio); } 35 AUE_NULL UNIMPL statfs 36 AUE_NULL NOPROTO { int sync(void); } 37 AUE_NULL STD { int svr4_sys_kill(int pid, int signum); } 38 AUE_NULL UNIMPL fstatfs 39 AUE_NULL STD { int svr4_sys_pgrpsys(int cmd, int pid, \ int pgid); } 40 AUE_NULL UNIMPL xenix 41 AUE_NULL NOPROTO { int dup(u_int fd); } 42 AUE_NULL NOPROTO { int pipe(void); } 43 AUE_NULL STD { int svr4_sys_times(struct tms *tp); } 44 AUE_NULL UNIMPL profil 45 AUE_NULL UNIMPL plock 46 AUE_NULL NOPROTO { int setgid(gid_t gid); } 47 AUE_NULL NOPROTO { gid_t getgid(void); } 48 AUE_NULL STD { int svr4_sys_signal(int signum, \ svr4_sig_t handler); } 49 AUE_NULL STD { int svr4_sys_msgsys(int what, int a2, \ int a3, int a4, int a5); } 50 AUE_NULL STD { int svr4_sys_sysarch(int op, void *a1); } 51 AUE_NULL UNIMPL acct 52 AUE_NULL STD { int svr4_sys_shmsys(int what, int a2, \ int a3, int a4, int a5); } 53 AUE_NULL STD { int svr4_sys_semsys(int what, int a2, \ int a3, int a4, int a5); } 54 AUE_NULL STD { int svr4_sys_ioctl(int fd, u_long com, \ caddr_t data); } 55 AUE_NULL UNIMPL uadmin 56 AUE_NULL UNIMPL exch 57 AUE_NULL STD { int svr4_sys_utssys(void *a1, void *a2, \ int sel, void *a3); } 58 AUE_NULL NOPROTO { int fsync(int fd); } 59 AUE_NULL STD { int svr4_sys_execve(char *path, \ char **argp, char **envp); } 60 AUE_NULL NOPROTO { int umask(int newmask); } 61 AUE_NULL NOPROTO { int chroot(char *path); } 62 AUE_NULL STD { int svr4_sys_fcntl(int fd, int cmd, \ char *arg); } 63 AUE_NULL STD { int svr4_sys_ulimit(int cmd, \ long newlimit); } 64 AUE_NULL UNIMPL reserved 65 AUE_NULL UNIMPL reserved 66 AUE_NULL UNIMPL reserved 67 AUE_NULL UNIMPL reserved 68 AUE_NULL UNIMPL reserved 69 AUE_NULL UNIMPL reserved 70 AUE_NULL UNIMPL advfs 71 AUE_NULL UNIMPL unadvfs 72 AUE_NULL UNIMPL rmount 73 AUE_NULL UNIMPL rumount 74 AUE_NULL UNIMPL rfstart 75 AUE_NULL UNIMPL sigret 76 AUE_NULL UNIMPL rdebug 77 AUE_NULL UNIMPL rfstop 78 AUE_NULL UNIMPL rfsys 79 AUE_NULL NOPROTO { int rmdir(char *path); } 80 AUE_NULL NOPROTO { int mkdir(char *path, int mode); } 81 AUE_NULL STD { int svr4_sys_getdents(int fd, char *buf, \ int nbytes); } 82 AUE_NULL UNIMPL libattach 83 AUE_NULL UNIMPL libdetach 84 AUE_NULL UNIMPL sysfs 85 AUE_NULL STD { int svr4_sys_getmsg(int fd, \ struct svr4_strbuf *ctl, \ struct svr4_strbuf *dat, int *flags); } 86 AUE_NULL STD { int svr4_sys_putmsg(int fd, \ struct svr4_strbuf *ctl, \ struct svr4_strbuf *dat, int flags); } 87 AUE_NULL STD { int svr4_sys_poll(struct pollfd *fds, \ unsigned int nfds, int timeout); } 88 AUE_NULL STD { int svr4_sys_lstat(char *path, \ struct svr4_stat *ub); } 89 AUE_NULL NOPROTO { int symlink(char *path, char *link); } 90 AUE_NULL NOPROTO { int readlink(char *path, char *buf, \ int count); } 91 AUE_NULL NOPROTO { int getgroups(u_int gidsetsize, \ gid_t *gidset); } 92 AUE_NULL NOPROTO { int setgroups(u_int gidsetsize, \ gid_t *gidset); } 93 AUE_NULL NOPROTO { int fchmod(int fd, int mode); } 94 AUE_NULL NOPROTO { int fchown(int fd, int uid, int gid); } 95 AUE_NULL STD { int svr4_sys_sigprocmask(int how, \ svr4_sigset_t *set, \ svr4_sigset_t *oset); } 96 AUE_NULL STD { int svr4_sys_sigsuspend( \ svr4_sigset_t *ss); } 97 AUE_NULL STD { int svr4_sys_sigaltstack( \ struct svr4_sigaltstack *nss, \ struct svr4_sigaltstack *oss); } 98 AUE_NULL STD { int svr4_sys_sigaction(int signum, \ struct svr4_sigaction *nsa, \ struct svr4_sigaction *osa); } 99 AUE_NULL STD { int svr4_sys_sigpending(int what, \ svr4_sigset_t *mask); } 100 AUE_NULL STD { int svr4_sys_context(int func, \ struct svr4_ucontext *uc); } 101 AUE_NULL UNIMPL evsys 102 AUE_NULL UNIMPL evtrapret 103 AUE_NULL STD { int svr4_sys_statvfs(char *path, \ struct svr4_statvfs *fs); } 104 AUE_NULL STD { int svr4_sys_fstatvfs(int fd, \ struct svr4_statvfs *fs); } 105 AUE_NULL UNIMPL whoknows 106 AUE_NULL UNIMPL nfssvc 107 AUE_NULL STD { int svr4_sys_waitsys(int grp, int id, \ union svr4_siginfo *info, int options); } 108 AUE_NULL UNIMPL sigsendsys 109 AUE_NULL STD { int svr4_sys_hrtsys(int cmd, int fun, \ int sub, void *rv1, void *rv2); } 110 AUE_NULL UNIMPL acancel 111 AUE_NULL UNIMPL async 112 AUE_NULL UNIMPL priocntlsys 113 AUE_NULL STD { int svr4_sys_pathconf(char *path, \ int name); } 114 AUE_NULL UNIMPL mincore 115 AUE_NULL STD { caddr_t svr4_sys_mmap(caddr_t addr, \ svr4_size_t len, int prot, int flags, \ int fd, svr4_off_t pos); } 116 AUE_NULL NOPROTO { int mprotect(void *addr, int len, \ int prot); } 117 AUE_NULL NOPROTO { int munmap(void *addr, int len); } 118 AUE_NULL STD { int svr4_sys_fpathconf(int fd, int name); } 119 AUE_NULL NOPROTO { int vfork(void); } 120 AUE_NULL NOPROTO { int fchdir(int fd); } 121 AUE_NULL NOPROTO { int readv(int fd, struct iovec *iovp, \ u_int iovcnt); } 122 AUE_NULL NOPROTO { int writev(int fd, struct iovec *iovp, \ u_int iovcnt); } 123 AUE_NULL STD { int svr4_sys_xstat(int two, char *path, \ struct svr4_xstat *ub); } 124 AUE_NULL STD { int svr4_sys_lxstat(int two, char *path, \ struct svr4_xstat *ub); } 125 AUE_NULL STD { int svr4_sys_fxstat(int two, int fd, \ struct svr4_xstat *sb); } 126 AUE_NULL STD { int svr4_sys_xmknod(int two, char *path, \ svr4_mode_t mode, svr4_dev_t dev); } 127 AUE_NULL UNIMPL clocal 128 AUE_NULL STD { int svr4_sys_setrlimit(int which, \ const struct svr4_rlimit *rlp); } 129 AUE_NULL STD { int svr4_sys_getrlimit(int which, \ struct svr4_rlimit *rlp); } 130 AUE_NULL NOPROTO { int lchown(char *path, uid_t uid, \ gid_t gid); } 131 AUE_NULL STD { int svr4_sys_memcntl(void * addr, \ svr4_size_t len, int cmd, void * arg, \ int attr, int mask); } 132 AUE_NULL UNIMPL getpmsg 133 AUE_NULL UNIMPL putpmsg 134 AUE_NULL NOPROTO { int rename(char *from, char *to); } 135 AUE_NULL STD { int svr4_sys_uname( \ struct svr4_utsname* name, int dummy); } 136 AUE_NULL NOPROTO { int setegid(gid_t egid); } 137 AUE_NULL STD { int svr4_sys_sysconfig(int name); } 138 AUE_NULL NOPROTO { int adjtime(struct timeval *delta, \ struct timeval *olddelta); } 139 AUE_NULL STD { long svr4_sys_systeminfo(int what, \ char *buf, long len); } 140 AUE_NULL UNIMPL notused 141 AUE_NULL NOPROTO { int seteuid(uid_t euid); } 142 AUE_NULL UNIMPL vtrace ; fork1 143 AUE_NULL UNIMPL { int fork(void); } 144 AUE_NULL UNIMPL sigtimedwait 145 AUE_NULL UNIMPL lwp_info 146 AUE_NULL UNIMPL yield 147 AUE_NULL UNIMPL lwp_sema_wait 148 AUE_NULL UNIMPL lwp_sema_post 149 AUE_NULL UNIMPL lwp_sema_trywait 150 AUE_NULL UNIMPL notused 151 AUE_NULL UNIMPL notused 152 AUE_NULL UNIMPL modctl 153 AUE_NULL STD { int svr4_sys_fchroot(int fd); } 154 AUE_NULL STD { int svr4_sys_utimes(char *path, \ struct timeval *tptr); } 155 AUE_NULL STD { int svr4_sys_vhangup(void); } 156 AUE_NULL STD { int svr4_sys_gettimeofday( \ struct timeval *tp); } 157 AUE_NULL NOPROTO { int getitimer(u_int which, \ struct itimerval *itv); } 158 AUE_NULL NOPROTO { int setitimer(u_int which, \ struct itimerval *itv, \ struct itimerval *oitv); } 159 AUE_NULL UNIMPL lwp_create 160 AUE_NULL UNIMPL lwp_exit 161 AUE_NULL UNIMPL lwp_suspend 162 AUE_NULL UNIMPL lwp_continue 163 AUE_NULL UNIMPL lwp_kill 164 AUE_NULL UNIMPL lwp_self 165 AUE_NULL UNIMPL lwp_getprivate 166 AUE_NULL UNIMPL lwp_setprivate 167 AUE_NULL UNIMPL lwp_wait 168 AUE_NULL UNIMPL lwp_mutex_unlock 169 AUE_NULL UNIMPL lwp_mutex_lock 170 AUE_NULL UNIMPL lwp_cond_wait 171 AUE_NULL UNIMPL lwp_cond_signal 172 AUE_NULL UNIMPL lwp_cond_broadcast 173 AUE_NULL UNIMPL { ssize_t svr4_sys_pread(int fd, void *buf, \ size_t nbyte, svr4_off_t off); } 174 AUE_NULL UNIMPL { ssize_t svr4_sys_pwrite(int fd, \ const void *buf, size_t nbyte, \ svr4_off_t off); } 175 AUE_NULL STD { svr4_off64_t svr4_sys_llseek(int fd, \ long offset1, long offset2, int whence); } 176 AUE_NULL UNIMPL inst_sync 177 AUE_NULL UNIMPL whoknows 178 AUE_NULL UNIMPL kaio 179 AUE_NULL UNIMPL whoknows 180 AUE_NULL UNIMPL whoknows 181 AUE_NULL UNIMPL whoknows 182 AUE_NULL UNIMPL whoknows 183 AUE_NULL UNIMPL whoknows 184 AUE_NULL UNIMPL tsolsys 185 AUE_NULL STD { int svr4_sys_acl(char *path, int cmd, \ int num, struct svr4_aclent *buf); } 186 AUE_NULL STD { int svr4_sys_auditsys(int code, int a1, \ int a2, int a3, int a4, int a5); } 187 AUE_NULL UNIMPL processor_bind 188 AUE_NULL UNIMPL processor_info 189 AUE_NULL UNIMPL p_online 190 AUE_NULL UNIMPL sigqueue 191 AUE_NULL UNIMPL clock_gettime 192 AUE_NULL UNIMPL clock_settime 193 AUE_NULL UNIMPL clock_getres 194 AUE_NULL UNIMPL timer_create 195 AUE_NULL UNIMPL timer_delete 196 AUE_NULL UNIMPL timer_settime 197 AUE_NULL UNIMPL timer_gettime 198 AUE_NULL UNIMPL timer_overrun 199 AUE_NULL NOPROTO { int nanosleep( \ const struct timespec *rqtp, \ struct timespec *rmtp); } 200 AUE_NULL STD { int svr4_sys_facl(int fd, int cmd, \ int num, struct svr4_aclent *buf); } 201 AUE_NULL UNIMPL door 202 AUE_NULL NOPROTO { int setreuid(int ruid, int euid); } 203 AUE_NULL NOPROTO { int setregid(int rgid, int egid); } 204 AUE_NULL UNIMPL install_utrap 205 AUE_NULL UNIMPL signotify 206 AUE_NULL UNIMPL schedctl 207 AUE_NULL UNIMPL pset 208 AUE_NULL UNIMPL whoknows 209 AUE_NULL STD { int svr4_sys_resolvepath(const char *path, \ char *buf, size_t bufsiz); } 210 AUE_NULL UNIMPL signotifywait 211 AUE_NULL UNIMPL lwp_sigredirect 212 AUE_NULL UNIMPL lwp_alarm 213 AUE_NULL STD { int svr4_sys_getdents64(int fd, \ struct svr4_dirent64 *dp, int nbytes); } ;213 AUE_NULL UNIMPL getdents64 214 AUE_NULL STD { caddr_t svr4_sys_mmap64(void *addr, \ svr4_size_t len, int prot, int flags, \ int fd, svr4_off64_t pos); } 215 AUE_NULL STD { int svr4_sys_stat64(char *path, \ struct svr4_stat64 *sb); } 216 AUE_NULL STD { int svr4_sys_lstat64(char *path, \ struct svr4_stat64 *sb); } 217 AUE_NULL STD { int svr4_sys_fstat64(int fd, \ struct svr4_stat64 *sb); } 218 AUE_NULL STD { int svr4_sys_statvfs64(char *path, \ struct svr4_statvfs64 *fs); } 219 AUE_NULL STD { int svr4_sys_fstatvfs64(int fd, \ struct svr4_statvfs64 *fs); } 220 AUE_NULL STD { int svr4_sys_setrlimit64(int which, \ const struct svr4_rlimit64 *rlp); } 221 AUE_NULL STD { int svr4_sys_getrlimit64(int which, \ struct svr4_rlimit64 *rlp); } 222 AUE_NULL UNIMPL pread64 223 AUE_NULL UNIMPL pwrite64 224 AUE_NULL STD { int svr4_sys_creat64(char *path, \ int mode); } 225 AUE_NULL STD { int svr4_sys_open64(char *path, int flags, \ int mode); } 226 AUE_NULL UNIMPL rpcsys 227 AUE_NULL UNIMPL whoknows 228 AUE_NULL UNIMPL whoknows 229 AUE_NULL UNIMPL whoknows 230 AUE_NULL STD { int svr4_sys_socket(int domain, int type, \ int protocol); } 231 AUE_NULL NOPROTO { int socketpair(int domain, int type, \ int protocol, int *rsv); } 232 AUE_NULL NOPROTO { int bind(int s, \ const struct sockaddr *name, \ int namelen); } 233 AUE_NULL NOPROTO { int listen(int s, int backlog); } 234 AUE_NULL NOPROTO { int accept(int s, struct sockaddr *name, \ int *anamelen); } 235 AUE_NULL NOPROTO { int connect(int s, \ const struct sockaddr *name, \ int namelen); } 236 AUE_NULL NOPROTO { int shutdown(int s, int how); } 237 AUE_NULL STD { int svr4_sys_recv(int s, caddr_t buf, \ int len, int flags); } 238 AUE_NULL NOPROTO { ssize_t recvfrom(int s, void *buf, \ size_t len, int flags, \ struct sockaddr *from, \ int *fromlenaddr); } 239 AUE_NULL NOPROTO { ssize_t recvmsg(int s, struct msghdr *msg, \ int flags); } 240 AUE_NULL STD { int svr4_sys_send(int s, caddr_t buf, \ int len, int flags); } 241 AUE_NULL NOPROTO { ssize_t sendmsg(int s, \ const struct msghdr *msg, int flags); } 242 AUE_NULL STD { ssize_t svr4_sys_sendto(int s, void *buf, \ size_t len, int flags, \ struct sockaddr *to, int tolen); } 243 AUE_NULL NOPROTO { int getpeername(int fdes, \ struct sockaddr *asa, int *alen); } 244 AUE_NULL NOPROTO { int getsockname(int fdes, \ struct sockaddr *asa, int *alen); } 245 AUE_NULL NOPROTO { int getsockopt(int s, int level, int name, \ void *val, int *avalsize); } 246 AUE_NULL NOPROTO { int setsockopt(int s, int level, int name, \ const void *val, int valsize); } 247 AUE_NULL UNIMPL sockconfig 248 AUE_NULL UNIMPL { int ntp_gettime(struct ntptimeval *ntvp); } 249 AUE_NULL UNIMPL { int ntp_adjtime(struct timex *tp); } diff --git a/sys/i386/ibcs2/ibcs2_fcntl.c b/sys/i386/ibcs2/ibcs2_fcntl.c index fddfcb59321b..2902da74bcdf 100644 --- a/sys/i386/ibcs2/ibcs2_fcntl.c +++ b/sys/i386/ibcs2/ibcs2_fcntl.c @@ -1,315 +1,315 @@ /*- * Copyright (c) 1995 Scott Bartram * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "opt_spx_hack.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static void cvt_iflock2flock(struct ibcs2_flock *, struct flock *); static void cvt_flock2iflock(struct flock *, struct ibcs2_flock *); static int cvt_o_flags(int); static int oflags2ioflags(int); static int ioflags2oflags(int); static int cvt_o_flags(flags) int flags; { int r = 0; /* convert mode into NetBSD mode */ if (flags & IBCS2_O_WRONLY) r |= O_WRONLY; if (flags & IBCS2_O_RDWR) r |= O_RDWR; if (flags & (IBCS2_O_NDELAY | IBCS2_O_NONBLOCK)) r |= O_NONBLOCK; if (flags & IBCS2_O_APPEND) r |= O_APPEND; if (flags & IBCS2_O_SYNC) r |= O_FSYNC; if (flags & IBCS2_O_CREAT) r |= O_CREAT; if (flags & IBCS2_O_TRUNC) r |= O_TRUNC /* | O_CREAT ??? */; if (flags & IBCS2_O_EXCL) r |= O_EXCL; if (flags & IBCS2_O_RDONLY) r |= O_RDONLY; if (flags & IBCS2_O_PRIV) r |= O_EXLOCK; if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY; return r; } static void cvt_flock2iflock(flp, iflp) struct flock *flp; struct ibcs2_flock *iflp; { switch (flp->l_type) { case F_RDLCK: iflp->l_type = IBCS2_F_RDLCK; break; case F_WRLCK: iflp->l_type = IBCS2_F_WRLCK; break; case F_UNLCK: iflp->l_type = IBCS2_F_UNLCK; break; } iflp->l_whence = (short)flp->l_whence; iflp->l_start = (ibcs2_off_t)flp->l_start; iflp->l_len = (ibcs2_off_t)flp->l_len; iflp->l_sysid = flp->l_sysid; iflp->l_pid = (ibcs2_pid_t)flp->l_pid; } #ifdef DEBUG_IBCS2 static void print_flock(struct flock *flp) { printf("flock: start=%x len=%x pid=%d type=%d whence=%d\n", (int)flp->l_start, (int)flp->l_len, (int)flp->l_pid, flp->l_type, flp->l_whence); } #endif static void cvt_iflock2flock(iflp, flp) struct ibcs2_flock *iflp; struct flock *flp; { flp->l_start = (off_t)iflp->l_start; flp->l_len = (off_t)iflp->l_len; flp->l_pid = (pid_t)iflp->l_pid; switch (iflp->l_type) { case IBCS2_F_RDLCK: flp->l_type = F_RDLCK; break; case IBCS2_F_WRLCK: flp->l_type = F_WRLCK; break; case IBCS2_F_UNLCK: flp->l_type = F_UNLCK; break; } flp->l_whence = iflp->l_whence; flp->l_sysid = iflp->l_sysid; } /* convert iBCS2 mode into NetBSD mode */ static int ioflags2oflags(flags) int flags; { int r = 0; if (flags & IBCS2_O_RDONLY) r |= O_RDONLY; if (flags & IBCS2_O_WRONLY) r |= O_WRONLY; if (flags & IBCS2_O_RDWR) r |= O_RDWR; if (flags & IBCS2_O_NDELAY) r |= O_NONBLOCK; if (flags & IBCS2_O_APPEND) r |= O_APPEND; if (flags & IBCS2_O_SYNC) r |= O_FSYNC; if (flags & IBCS2_O_NONBLOCK) r |= O_NONBLOCK; if (flags & IBCS2_O_CREAT) r |= O_CREAT; if (flags & IBCS2_O_TRUNC) r |= O_TRUNC; if (flags & IBCS2_O_EXCL) r |= O_EXCL; if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY; return r; } /* convert NetBSD mode into iBCS2 mode */ static int oflags2ioflags(flags) int flags; { int r = 0; if (flags & O_RDONLY) r |= IBCS2_O_RDONLY; if (flags & O_WRONLY) r |= IBCS2_O_WRONLY; if (flags & O_RDWR) r |= IBCS2_O_RDWR; if (flags & O_NDELAY) r |= IBCS2_O_NONBLOCK; if (flags & O_APPEND) r |= IBCS2_O_APPEND; if (flags & O_FSYNC) r |= IBCS2_O_SYNC; if (flags & O_NONBLOCK) r |= IBCS2_O_NONBLOCK; if (flags & O_CREAT) r |= IBCS2_O_CREAT; if (flags & O_TRUNC) r |= IBCS2_O_TRUNC; if (flags & O_EXCL) r |= IBCS2_O_EXCL; if (flags & O_NOCTTY) r |= IBCS2_O_NOCTTY; return r; } int ibcs2_open(td, uap) struct thread *td; struct ibcs2_open_args *uap; { struct proc *p; char *path; int flags, noctty, ret; p = td->td_proc; noctty = uap->flags & IBCS2_O_NOCTTY; flags = cvt_o_flags(uap->flags); if (uap->flags & O_CREAT) CHECKALTCREAT(td, uap->path, &path); else CHECKALTEXIST(td, uap->path, &path); ret = kern_open(td, path, UIO_SYSSPACE, flags, uap->mode); #ifdef SPX_HACK if (ret == ENXIO) { if (!strcmp(path, "/compat/ibcs2/dev/spx")) ret = spx_open(td); free(path, M_TEMP); } else #endif /* SPX_HACK */ free(path, M_TEMP); PROC_LOCK(p); if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { struct file *fp; int error; error = fget(td, td->td_retval[0], CAP_IOCTL, &fp); PROC_UNLOCK(p); if (error) return (EBADF); /* ignore any error, just give it a try */ if (fp->f_type == DTYPE_VNODE) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred, td); fdrop(fp, td); } else PROC_UNLOCK(p); return ret; } int ibcs2_creat(td, uap) struct thread *td; struct ibcs2_creat_args *uap; { char *path; int error; CHECKALTCREAT(td, uap->path, &path); error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC, uap->mode); free(path, M_TEMP); return (error); } int ibcs2_access(td, uap) struct thread *td; struct ibcs2_access_args *uap; { char *path; int error; CHECKALTEXIST(td, uap->path, &path); - error = kern_access(td, path, UIO_SYSSPACE, uap->flags); + error = kern_access(td, path, UIO_SYSSPACE, uap->amode); free(path, M_TEMP); return (error); } int ibcs2_fcntl(td, uap) struct thread *td; struct ibcs2_fcntl_args *uap; { intptr_t arg; int error; struct flock fl; struct ibcs2_flock ifl; arg = (intptr_t)uap->arg; switch(uap->cmd) { case IBCS2_F_DUPFD: return (kern_fcntl(td, uap->fd, F_DUPFD, arg)); case IBCS2_F_GETFD: return (kern_fcntl(td, uap->fd, F_GETFD, arg)); case IBCS2_F_SETFD: return (kern_fcntl(td, uap->fd, F_SETFD, arg)); case IBCS2_F_GETFL: error = kern_fcntl(td, uap->fd, F_GETFL, arg); if (error) return error; td->td_retval[0] = oflags2ioflags(td->td_retval[0]); return error; case IBCS2_F_SETFL: return (kern_fcntl(td, uap->fd, F_SETFL, ioflags2oflags(arg))); case IBCS2_F_GETLK: { error = copyin((caddr_t)uap->arg, (caddr_t)&ifl, ibcs2_flock_len); if (error) return error; cvt_iflock2flock(&ifl, &fl); error = kern_fcntl(td, uap->fd, F_GETLK, (intptr_t)&fl); if (error) return error; cvt_flock2iflock(&fl, &ifl); return copyout((caddr_t)&ifl, (caddr_t)uap->arg, ibcs2_flock_len); } case IBCS2_F_SETLK: { error = copyin((caddr_t)uap->arg, (caddr_t)&ifl, ibcs2_flock_len); if (error) return error; cvt_iflock2flock(&ifl, &fl); return (kern_fcntl(td, uap->fd, F_SETLK, (intptr_t)&fl)); } case IBCS2_F_SETLKW: { error = copyin((caddr_t)uap->arg, (caddr_t)&ifl, ibcs2_flock_len); if (error) return error; cvt_iflock2flock(&ifl, &fl); return (kern_fcntl(td, uap->fd, F_SETLKW, (intptr_t)&fl)); } } return ENOSYS; } diff --git a/sys/i386/ibcs2/syscalls.master b/sys/i386/ibcs2/syscalls.master index 9d0eda612f94..fd06d1ed6197 100644 --- a/sys/i386/ibcs2/syscalls.master +++ b/sys/i386/ibcs2/syscalls.master @@ -1,204 +1,204 @@ $FreeBSD$ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 ; System call name/number master file (or rather, slave, from IBCS2). ; Processed to created ibcs2_sysent.c, ibcs2_syscalls.c and ibcs2_syscall.h. ; Columns: number audit type nargs name alt{name,tag,rtyp}/comments ; number system call number, must be in order ; audit the audit event associated with the system call ; A value of AUE_NULL means no auditing, but it also means that ; there is no audit event for the call at this time. For the ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, OBSOL, UNIMPL, COMPAT ; name psuedo-prototype of syscall routine ; If one of the following alts is different, then all appear: ; altname name of system call if different ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL/OBSOL, name continues with comments ; types: ; STD always included ; COMPAT included on COMPAT #ifdef ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only #include #include #include #include #include #include ; #ifdef's, etc. may be included, and are copied to the output files. 0 AUE_NULL NOPROTO { int nosys(void); } syscall nosys_args int 1 AUE_EXIT NOPROTO { void sys_exit(int rval); } exit \ sys_exit_args void 2 AUE_FORK NOPROTO { int fork(void); } 3 AUE_NULL STD { int ibcs2_read(int fd, char *buf, \ u_int nbytes); } 4 AUE_NULL NOPROTO { int write(int fd, char *buf, \ u_int nbytes); } 5 AUE_OPEN_RWTC STD { int ibcs2_open(char *path, int flags, \ int mode); } 6 AUE_CLOSE NOPROTO { int close(int fd); } 7 AUE_WAIT4 STD { int ibcs2_wait(int a1, int a2, int a3); } 8 AUE_CREAT STD { int ibcs2_creat(char *path, int mode); } 9 AUE_LINK NOPROTO { int link(char *path, char *link); } 10 AUE_UNLINK STD { int ibcs2_unlink(char *path); } 11 AUE_EXECVE STD { int ibcs2_execv(char *path, char **argp); } 12 AUE_CHDIR STD { int ibcs2_chdir(char *path); } 13 AUE_NULL STD { int ibcs2_time(ibcs2_time_t *tp); } 14 AUE_MKNOD STD { int ibcs2_mknod(char* path, int mode, \ int dev); } 15 AUE_CHMOD STD { int ibcs2_chmod(char *path, int mode); } 16 AUE_CHOWN STD { int ibcs2_chown(char *path, int uid, \ int gid); } 17 AUE_NULL NOPROTO { int obreak(caddr_t nsize); } 18 AUE_STAT STD { int ibcs2_stat(char* path, \ struct ibcs2_stat *st); } 19 AUE_LSEEK STD { long ibcs2_lseek(int fd, long offset, \ int whence); } 20 AUE_NULL NOPROTO { pid_t getpid(void); } 21 AUE_MOUNT STD { int ibcs2_mount(char *special, char *dir, \ int flags, int fstype, char *data, \ int len); } 22 AUE_UMOUNT STD { int ibcs2_umount(char *name); } 23 AUE_SETUID STD { int ibcs2_setuid(int uid); } 24 AUE_GETUID NOPROTO { uid_t getuid(void); } 25 AUE_SETTIMEOFDAY STD { int ibcs2_stime(long *timep); } 26 AUE_PTRACE NOPROTO { int ptrace(int req, pid_t pid, \ caddr_t addr, int data); } 27 AUE_NULL STD { int ibcs2_alarm(unsigned sec); } 28 AUE_FSTAT STD { int ibcs2_fstat(int fd, \ struct ibcs2_stat *st); } 29 AUE_NULL STD { int ibcs2_pause(void); } 30 AUE_NULL STD { int ibcs2_utime(char *path, \ struct ibcs2_utimbuf *buf); } 31 AUE_NULL UNIMPL ibcs2_stty 32 AUE_NULL UNIMPL ibcs2_gtty -33 AUE_ACCESS STD { int ibcs2_access(char *path, int flags); } +33 AUE_ACCESS STD { int ibcs2_access(char *path, int amode); } 34 AUE_NICE STD { int ibcs2_nice(int incr); } 35 AUE_STATFS STD { int ibcs2_statfs(char *path, \ struct ibcs2_statfs *buf, int len, \ int fstype); } 36 AUE_NULL NOPROTO { int sync(void); } 37 AUE_KILL STD { int ibcs2_kill(int pid, int signo); } 38 AUE_FSTATFS STD { int ibcs2_fstatfs(int fd, \ struct ibcs2_statfs *buf, int len, \ int fstype); } 39 AUE_NULL STD { int ibcs2_pgrpsys(int type, caddr_t dummy, \ int pid, int pgid); } 40 AUE_NULL STD { int ibcs2_xenix(int a1, int a2, int a3, \ int a4, int a5); } 41 AUE_NULL NOPROTO { int dup(u_int fd); } 42 AUE_PIPE NOPROTO { int pipe(void); } 43 AUE_NULL STD { int ibcs2_times(struct tms *tp); } 44 AUE_PROFILE NOPROTO { int profil(caddr_t samples, u_int size, \ u_int offset, u_int scale); } 45 AUE_NULL STD { int ibcs2_plock(int cmd); } 46 AUE_SETGID STD { int ibcs2_setgid(int gid); } 47 AUE_GETGID NOPROTO { gid_t getgid(void); } 48 AUE_NULL STD { int ibcs2_sigsys(int sig, ibcs2_sig_t fp); } 49 AUE_MSGSYS STD { int ibcs2_msgsys(int which, int a2, \ int a3, int a4, int a5, int a6); } 50 AUE_NULL STD { int ibcs2_sysi86(int cmd, int *arg); } 51 AUE_NULL UNIMPL ibcs2_acct 52 AUE_SHMSYS STD { int ibcs2_shmsys(int which, int a2, \ int a3, int a4); } 53 AUE_SEMSYS STD { int ibcs2_semsys(int which, int a2, \ int a3, int a4, int a5); } 54 AUE_IOCTL STD { int ibcs2_ioctl(int fd, int cmd, \ caddr_t data); } 55 AUE_NULL STD { int ibcs2_uadmin(int cmd, int func, \ caddr_t data); } 56 AUE_NULL UNIMPL nosys 57 AUE_NULL STD { int ibcs2_utssys(int a1, int a2, \ int flag); } 58 AUE_FSYNC NOPROTO { int fsync(int fd); } 59 AUE_EXECVE STD { int ibcs2_execve(char *path, char **argp, \ char **envp); } 60 AUE_UMASK NOPROTO { int umask(int newmask); } 61 AUE_CHROOT NOPROTO { int chroot(char *path); } 62 AUE_FCNTL STD { int ibcs2_fcntl(int fd, int cmd, \ char *arg); } 63 AUE_NULL STD { long ibcs2_ulimit(int cmd, int newlimit); } 64 AUE_NULL UNIMPL reserved for unix/pc 65 AUE_NULL UNIMPL reserved for unix/pc 66 AUE_NULL UNIMPL reserved for unix/pc 67 AUE_NULL UNIMPL reserved for unix/pc 68 AUE_NULL UNIMPL reserved for unix/pc 69 AUE_NULL UNIMPL reserved for unix/pc 70 AUE_NULL OBSOL rfs_advfs 71 AUE_NULL OBSOL rfs_unadvfs 72 AUE_NULL OBSOL rfs_rmount 73 AUE_NULL OBSOL rfs_rumount 74 AUE_NULL OBSOL rfs_rfstart 75 AUE_NULL OBSOL rfs_sigret 76 AUE_NULL OBSOL rfs_rdebug 77 AUE_NULL OBSOL rfs_rfstop 78 AUE_NULL UNIMPL rfs_rfsys 79 AUE_RMDIR STD { int ibcs2_rmdir(char *path); } 80 AUE_MKDIR STD { int ibcs2_mkdir(char *path, int mode); } 81 AUE_GETDIRENTRIES STD { int ibcs2_getdents(int fd, char *buf, \ int nbytes); } 82 AUE_NULL UNIMPL nosys 83 AUE_NULL UNIMPL nosys 84 AUE_NULL STD { int ibcs2_sysfs(int cmd, caddr_t d1, \ char *buf); } 85 AUE_GETMSG STD { int ibcs2_getmsg(int fd, \ struct ibcs2_stropts *ctl, \ struct ibcs2_stropts *dat, int *flags); } 86 AUE_PUTMSG STD { int ibcs2_putmsg(int fd, \ struct ibcs2_stropts *ctl, \ struct ibcs2_stropts *dat, int flags); } 87 AUE_POLL NOPROTO { int poll(struct pollfd *fds, u_int nfds, \ int timeout); } 88 AUE_NULL UNIMPL nosys 89 AUE_NULL STD { int ibcs2_secure(int cmd, int a1, int a2, \ int a3, int a4, int a5); } 90 AUE_SYMLINK STD { int ibcs2_symlink(char *path, \ char *link); } 91 AUE_LSTAT STD { int ibcs2_lstat(char *path, \ struct ibcs2_stat *st); } 92 AUE_READLINK STD { int ibcs2_readlink(char *path, char *buf, \ int count); } 93 AUE_NULL UNIMPL nosys 94 AUE_NULL UNIMPL nosys 95 AUE_NULL UNIMPL nosys 96 AUE_NULL UNIMPL nosys 97 AUE_NULL UNIMPL nosys 98 AUE_NULL UNIMPL nosys 99 AUE_NULL UNIMPL nosys 100 AUE_NULL UNIMPL nosys 101 AUE_NULL UNIMPL nosys 102 AUE_NULL UNIMPL nosys 103 AUE_NULL NOPROTO { int sigreturn( \ struct sigcontext *sigcntxp); } 104 AUE_NULL UNIMPL nosys 105 AUE_NULL STD { int ibcs2_isc(void); } 106 AUE_NULL UNIMPL nosys 107 AUE_NULL UNIMPL nosys 108 AUE_NULL UNIMPL nosys 109 AUE_NULL UNIMPL nosys 110 AUE_NULL UNIMPL nosys 111 AUE_NULL UNIMPL nosys 112 AUE_NULL UNIMPL nosys 113 AUE_NULL UNIMPL nosys 114 AUE_NULL UNIMPL nosys 115 AUE_NULL UNIMPL nosys 116 AUE_NULL UNIMPL nosys 117 AUE_NULL UNIMPL nosys 118 AUE_NULL UNIMPL nosys 119 AUE_NULL UNIMPL nosys 120 AUE_NULL UNIMPL nosys 121 AUE_NULL UNIMPL nosys 122 AUE_NULL UNIMPL nosys 123 AUE_NULL UNIMPL nosys 124 AUE_NULL UNIMPL nosys 125 AUE_NULL UNIMPL nosys 126 AUE_NULL UNIMPL nosys 127 AUE_NULL UNIMPL nosys diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master index 27ddef6703c2..2cf494263e8f 100644 --- a/sys/i386/linux/syscalls.master +++ b/sys/i386/linux/syscalls.master @@ -1,514 +1,514 @@ $FreeBSD$ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 ; System call name/number master file (or rather, slave, from LINUX). ; Processed to create linux_sysent.c, linux_proto.h and linux_syscall.h. ; Columns: number audit type nargs name alt{name,tag,rtyp}/comments ; number system call number, must be in order ; audit the audit event associated with the system call ; A value of AUE_NULL means no auditing, but it also means that ; there is no audit event for the call at this time. For the ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, OBSOL, UNIMPL ; name psuedo-prototype of syscall routine ; If one of the following alts is different, then all appear: ; altname name of system call if different ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL/OBSOL, name continues with comments ; types: ; STD always included ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only #include #include #include #include #include #include ; Isn't pretty, but there seems to be no other way to trap nosys #define nosys linux_nosys ; #ifdef's, etc. may be included, and are copied to the output files. 0 AUE_NULL UNIMPL setup 1 AUE_EXIT NOPROTO { void sys_exit(int rval); } exit \ sys_exit_args void 2 AUE_FORK STD { int linux_fork(void); } 3 AUE_NULL NOPROTO { int read(int fd, char *buf, \ u_int nbyte); } 4 AUE_NULL NOPROTO { int write(int fd, char *buf, \ u_int nbyte); } 5 AUE_OPEN_RWTC STD { int linux_open(char *path, l_int flags, \ l_int mode); } 6 AUE_CLOSE NOPROTO { int close(int fd); } 7 AUE_WAIT4 STD { int linux_waitpid(l_pid_t pid, \ l_int *status, l_int options); } 8 AUE_CREAT STD { int linux_creat(char *path, \ l_int mode); } 9 AUE_LINK STD { int linux_link(char *path, char *to); } 10 AUE_UNLINK STD { int linux_unlink(char *path); } 11 AUE_EXECVE STD { int linux_execve(char *path, char **argp, \ char **envp); } 12 AUE_CHDIR STD { int linux_chdir(char *path); } 13 AUE_NULL STD { int linux_time(l_time_t *tm); } 14 AUE_MKNOD STD { int linux_mknod(char *path, l_int mode, \ l_dev_t dev); } 15 AUE_CHMOD STD { int linux_chmod(char *path, \ l_mode_t mode); } 16 AUE_LCHOWN STD { int linux_lchown16(char *path, \ l_uid16_t uid, l_gid16_t gid); } 17 AUE_NULL UNIMPL break 18 AUE_STAT STD { int linux_stat(char *path, \ struct linux_stat *up); } 19 AUE_LSEEK STD { int linux_lseek(l_uint fdes, l_off_t off, \ l_int whence); } 20 AUE_GETPID STD { int linux_getpid(void); } 21 AUE_MOUNT STD { int linux_mount(char *specialfile, \ char *dir, char *filesystemtype, \ l_ulong rwflag, void *data); } 22 AUE_UMOUNT STD { int linux_oldumount(char *path); } 23 AUE_SETUID STD { int linux_setuid16(l_uid16_t uid); } 24 AUE_GETUID STD { int linux_getuid16(void); } 25 AUE_SETTIMEOFDAY STD { int linux_stime(void); } 26 AUE_PTRACE STD { int linux_ptrace(l_long req, l_long pid, \ l_long addr, l_long data); } 27 AUE_NULL STD { int linux_alarm(l_uint secs); } 28 AUE_FSTAT STD { int linux_fstat(l_uint fd, \ struct linux_stat *up); } 29 AUE_NULL STD { int linux_pause(void); } 30 AUE_UTIME STD { int linux_utime(char *fname, \ struct l_utimbuf *times); } 31 AUE_NULL UNIMPL stty 32 AUE_NULL UNIMPL gtty -33 AUE_ACCESS STD { int linux_access(char *path, l_int flags); } +33 AUE_ACCESS STD { int linux_access(char *path, l_int amode); } 34 AUE_NICE STD { int linux_nice(l_int inc); } 35 AUE_NULL UNIMPL ftime 36 AUE_SYNC NOPROTO { int sync(void); } 37 AUE_KILL STD { int linux_kill(l_int pid, l_int signum); } 38 AUE_RENAME STD { int linux_rename(char *from, char *to); } 39 AUE_MKDIR STD { int linux_mkdir(char *path, l_int mode); } 40 AUE_RMDIR STD { int linux_rmdir(char *path); } 41 AUE_DUP NOPROTO { int dup(u_int fd); } 42 AUE_PIPE STD { int linux_pipe(l_ulong *pipefds); } 43 AUE_NULL STD { int linux_times(struct l_times_argv *buf); } 44 AUE_NULL UNIMPL prof 45 AUE_NULL STD { int linux_brk(l_ulong dsend); } 46 AUE_SETGID STD { int linux_setgid16(l_gid16_t gid); } 47 AUE_GETGID STD { int linux_getgid16(void); } 48 AUE_NULL STD { int linux_signal(l_int sig, \ void *handler); } 49 AUE_GETEUID STD { int linux_geteuid16(void); } 50 AUE_GETEGID STD { int linux_getegid16(void); } 51 AUE_ACCT NOPROTO { int acct(char *path); } 52 AUE_UMOUNT STD { int linux_umount(char *path, l_int flags); } 53 AUE_NULL UNIMPL lock 54 AUE_IOCTL STD { int linux_ioctl(l_uint fd, l_uint cmd, \ l_ulong arg); } 55 AUE_FCNTL STD { int linux_fcntl(l_uint fd, l_uint cmd, \ l_ulong arg); } 56 AUE_NULL UNIMPL mpx 57 AUE_SETPGRP NOPROTO { int setpgid(int pid, int pgid); } 58 AUE_NULL UNIMPL ulimit 59 AUE_NULL STD { int linux_olduname(void); } 60 AUE_UMASK NOPROTO { int umask(int newmask); } 61 AUE_CHROOT NOPROTO { int chroot(char *path); } 62 AUE_NULL STD { int linux_ustat(l_dev_t dev, \ struct l_ustat *ubuf); } 63 AUE_DUP2 NOPROTO { int dup2(u_int from, u_int to); } 64 AUE_GETPPID STD { int linux_getppid(void); } 65 AUE_GETPGRP NOPROTO { int getpgrp(void); } 66 AUE_SETSID NOPROTO { int setsid(void); } 67 AUE_NULL STD { int linux_sigaction(l_int sig, \ l_osigaction_t *nsa, \ l_osigaction_t *osa); } 68 AUE_NULL STD { int linux_sgetmask(void); } 69 AUE_NULL STD { int linux_ssetmask(l_osigset_t mask); } 70 AUE_SETREUID STD { int linux_setreuid16(l_uid16_t ruid, \ l_uid16_t euid); } 71 AUE_SETREGID STD { int linux_setregid16(l_gid16_t rgid, \ l_gid16_t egid); } 72 AUE_NULL STD { int linux_sigsuspend(l_int hist0, \ l_int hist1, l_osigset_t mask); } 73 AUE_NULL STD { int linux_sigpending(l_osigset_t *mask); } 74 AUE_SYSCTL STD { int linux_sethostname(char *hostname, \ u_int len); } 75 AUE_SETRLIMIT STD { int linux_setrlimit(l_uint resource, \ struct l_rlimit *rlim); } 76 AUE_GETRLIMIT STD { int linux_old_getrlimit(l_uint resource, \ struct l_rlimit *rlim); } 77 AUE_GETRUSAGE NOPROTO { int getrusage(int who, \ struct rusage *rusage); } 78 AUE_NULL NOPROTO { int gettimeofday( \ struct timeval *tp, \ struct timezone *tzp); } 79 AUE_SETTIMEOFDAY NOPROTO { int settimeofday( \ struct timeval *tv, \ struct timezone *tzp); } 80 AUE_GETGROUPS STD { int linux_getgroups16(l_uint gidsetsize, \ l_gid16_t *gidset); } 81 AUE_SETGROUPS STD { int linux_setgroups16(l_uint gidsetsize, \ l_gid16_t *gidset); } 82 AUE_SELECT STD { int linux_old_select( \ struct l_old_select_argv *ptr); } 83 AUE_SYMLINK STD { int linux_symlink(char *path, char *to); } 84 AUE_LSTAT STD { int linux_lstat(char *path, struct ostat *up); } 85 AUE_READLINK STD { int linux_readlink(char *name, char *buf, \ l_int count); } 86 AUE_USELIB STD { int linux_uselib(char *library); } 87 AUE_SWAPON NOPROTO { int swapon(char *name); } 88 AUE_REBOOT STD { int linux_reboot(l_int magic1, \ l_int magic2, l_uint cmd, void *arg); } 89 AUE_GETDIRENTRIES STD { int linux_readdir(l_uint fd, \ struct l_dirent *dent, l_uint count); } 90 AUE_MMAP STD { int linux_mmap(struct l_mmap_argv *ptr); } 91 AUE_MUNMAP NOPROTO { int munmap(caddr_t addr, int len); } 92 AUE_TRUNCATE STD { int linux_truncate(char *path, \ l_ulong length); } 93 AUE_FTRUNCATE STD { int linux_ftruncate(int fd, long length); } 94 AUE_FCHMOD NOPROTO { int fchmod(int fd, int mode); } 95 AUE_FCHOWN NOPROTO { int fchown(int fd, int uid, int gid); } 96 AUE_GETPRIORITY STD { int linux_getpriority(int which, int who); } 97 AUE_SETPRIORITY NOPROTO { int setpriority(int which, int who, \ int prio); } 98 AUE_PROFILE UNIMPL profil 99 AUE_STATFS STD { int linux_statfs(char *path, \ struct l_statfs_buf *buf); } 100 AUE_FSTATFS STD { int linux_fstatfs(l_uint fd, \ struct l_statfs_buf *buf); } 101 AUE_NULL STD { int linux_ioperm(l_ulong start, \ l_ulong length, l_int enable); } 102 AUE_NULL STD { int linux_socketcall(l_int what, \ l_ulong args); } 103 AUE_NULL STD { int linux_syslog(l_int type, char *buf, \ l_int len); } 104 AUE_SETITIMER STD { int linux_setitimer(l_int which, \ struct l_itimerval *itv, \ struct l_itimerval *oitv); } 105 AUE_GETITIMER STD { int linux_getitimer(l_int which, \ struct l_itimerval *itv); } 106 AUE_STAT STD { int linux_newstat(char *path, \ struct l_newstat *buf); } 107 AUE_LSTAT STD { int linux_newlstat(char *path, \ struct l_newstat *buf); } 108 AUE_FSTAT STD { int linux_newfstat(l_uint fd, \ struct l_newstat *buf); } 109 AUE_NULL STD { int linux_uname(void); } 110 AUE_NULL STD { int linux_iopl(l_ulong level); } 111 AUE_NULL STD { int linux_vhangup(void); } 112 AUE_NULL UNIMPL idle 113 AUE_NULL STD { int linux_vm86old(void); } 114 AUE_WAIT4 STD { int linux_wait4(l_pid_t pid, \ l_uint *status, l_int options, \ struct l_rusage *rusage); } 115 AUE_SWAPOFF STD { int linux_swapoff(void); } 116 AUE_NULL STD { int linux_sysinfo(struct l_sysinfo *info); } 117 AUE_NULL STD { int linux_ipc(l_uint what, l_int arg1, \ l_int arg2, l_int arg3, void *ptr, \ l_long arg5); } 118 AUE_FSYNC NOPROTO { int fsync(int fd); } 119 AUE_SIGRETURN STD { int linux_sigreturn( \ struct l_sigframe *sfp); } 120 AUE_RFORK STD { int linux_clone(l_int flags, void *stack, \ void *parent_tidptr, void *tls, void * child_tidptr); } 121 AUE_SYSCTL STD { int linux_setdomainname(char *name, \ int len); } 122 AUE_NULL STD { int linux_newuname( \ struct l_new_utsname *buf); } 123 AUE_NULL STD { int linux_modify_ldt(l_int func, \ void *ptr, l_ulong bytecount); } 124 AUE_ADJTIME STD { int linux_adjtimex(void); } 125 AUE_MPROTECT STD { int linux_mprotect(caddr_t addr, int len, \ int prot); } 126 AUE_SIGPROCMASK STD { int linux_sigprocmask(l_int how, \ l_osigset_t *mask, l_osigset_t *omask); } 127 AUE_NULL STD { int linux_create_module(void); } 128 AUE_NULL STD { int linux_init_module(void); } 129 AUE_NULL STD { int linux_delete_module(void); } 130 AUE_NULL STD { int linux_get_kernel_syms(void); } 131 AUE_QUOTACTL STD { int linux_quotactl(void); } 132 AUE_GETPGID NOPROTO { int getpgid(int pid); } 133 AUE_FCHDIR NOPROTO { int fchdir(int fd); } 134 AUE_BDFLUSH STD { int linux_bdflush(void); } 135 AUE_NULL STD { int linux_sysfs(l_int option, \ l_ulong arg1, l_ulong arg2); } 136 AUE_PERSONALITY STD { int linux_personality(l_ulong per); } 137 AUE_NULL UNIMPL afs_syscall 138 AUE_SETFSUID STD { int linux_setfsuid16(l_uid16_t uid); } 139 AUE_SETFSGID STD { int linux_setfsgid16(l_gid16_t gid); } 140 AUE_LSEEK STD { int linux_llseek(l_int fd, l_ulong ohigh, \ l_ulong olow, l_loff_t *res, \ l_uint whence); } 141 AUE_GETDIRENTRIES STD { int linux_getdents(l_uint fd, \ void *dent, l_uint count); } 142 AUE_SELECT STD { int linux_select(l_int nfds, \ l_fd_set *readfds, l_fd_set *writefds, \ l_fd_set *exceptfds, \ struct l_timeval *timeout); } 143 AUE_FLOCK NOPROTO { int flock(int fd, int how); } 144 AUE_MSYNC STD { int linux_msync(l_ulong addr, \ l_size_t len, l_int fl); } 145 AUE_READV NOPROTO { int readv(int fd, struct iovec *iovp, \ u_int iovcnt); } 146 AUE_WRITEV NOPROTO { int writev(int fd, struct iovec *iovp, \ u_int iovcnt); } 147 AUE_GETSID STD { int linux_getsid(l_pid_t pid); } 148 AUE_NULL STD { int linux_fdatasync(l_uint fd); } 149 AUE_SYSCTL STD { int linux_sysctl( \ struct l___sysctl_args *args); } 150 AUE_MLOCK NOPROTO { int mlock(const void *addr, size_t len); } 151 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, size_t len); } 152 AUE_MLOCKALL NOPROTO { int mlockall(int how); } 153 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } 154 AUE_SCHED_SETPARAM NOPROTO { int sched_setparam(pid_t pid, \ const struct sched_param *param); } 155 AUE_SCHED_GETPARAM NOPROTO { int sched_getparam(pid_t pid, \ struct sched_param *param); } 156 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( \ l_pid_t pid, l_int policy, \ struct l_sched_param *param); } 157 AUE_SCHED_GETSCHEDULER STD { int linux_sched_getscheduler( \ l_pid_t pid); } 158 AUE_NULL NOPROTO { int sched_yield(void); } 159 AUE_SCHED_GET_PRIORITY_MAX STD { int linux_sched_get_priority_max( \ l_int policy); } 160 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( \ l_int policy); } 161 AUE_SCHED_RR_GET_INTERVAL NOPROTO { int sched_rr_get_interval(l_pid_t pid, \ struct l_timespec *interval); } 162 AUE_NULL STD { int linux_nanosleep( \ const struct l_timespec *rqtp, \ struct l_timespec *rmtp); } 163 AUE_NULL STD { int linux_mremap(l_ulong addr, \ l_ulong old_len, l_ulong new_len, \ l_ulong flags, l_ulong new_addr); } 164 AUE_SETRESUID STD { int linux_setresuid16(l_uid16_t ruid, \ l_uid16_t euid, l_uid16_t suid); } 165 AUE_GETRESUID STD { int linux_getresuid16(l_uid16_t *ruid, \ l_uid16_t *euid, l_uid16_t *suid); } 166 AUE_NULL STD { int linux_vm86(void); } 167 AUE_NULL STD { int linux_query_module(void); } 168 AUE_POLL NOPROTO { int poll(struct pollfd* fds, \ unsigned int nfds, long timeout); } 169 AUE_NULL STD { int linux_nfsservctl(void); } 170 AUE_SETRESGID STD { int linux_setresgid16(l_gid16_t rgid, \ l_gid16_t egid, l_gid16_t sgid); } 171 AUE_GETRESGID STD { int linux_getresgid16(l_gid16_t *rgid, \ l_gid16_t *egid, l_gid16_t *sgid); } 172 AUE_PRCTL STD { int linux_prctl(l_int option, l_int arg2, l_int arg3, \ l_int arg4, l_int arg5); } 173 AUE_NULL STD { int linux_rt_sigreturn( \ struct l_ucontext *ucp); } 174 AUE_NULL STD { int linux_rt_sigaction(l_int sig, \ l_sigaction_t *act, l_sigaction_t *oact, \ l_size_t sigsetsize); } 175 AUE_NULL STD { int linux_rt_sigprocmask(l_int how, \ l_sigset_t *mask, l_sigset_t *omask, \ l_size_t sigsetsize); } 176 AUE_NULL STD { int linux_rt_sigpending(l_sigset_t *set, \ l_size_t sigsetsize); } 177 AUE_NULL STD { int linux_rt_sigtimedwait(l_sigset_t *mask, \ l_siginfo_t *ptr, \ struct l_timeval *timeout, \ l_size_t sigsetsize); } 178 AUE_NULL STD { int linux_rt_sigqueueinfo(void); } 179 AUE_NULL STD { int linux_rt_sigsuspend( \ l_sigset_t *newset, \ l_size_t sigsetsize); } 180 AUE_PREAD STD { int linux_pread(l_uint fd, char *buf, \ l_size_t nbyte, l_loff_t offset); } 181 AUE_PWRITE STD { int linux_pwrite(l_uint fd, char *buf, \ l_size_t nbyte, l_loff_t offset); } 182 AUE_CHOWN STD { int linux_chown16(char *path, \ l_uid16_t uid, l_gid16_t gid); } 183 AUE_GETCWD STD { int linux_getcwd(char *buf, \ l_ulong bufsize); } 184 AUE_CAPGET STD { int linux_capget(struct l_user_cap_header *hdrp, \ struct l_user_cap_data *datap); } 185 AUE_CAPSET STD { int linux_capset(struct l_user_cap_header *hdrp, \ struct l_user_cap_data *datap); } 186 AUE_NULL STD { int linux_sigaltstack(l_stack_t *uss, \ l_stack_t *uoss); } 187 AUE_SENDFILE STD { int linux_sendfile(void); } 188 AUE_GETPMSG UNIMPL getpmsg 189 AUE_PUTPMSG UNIMPL putpmsg 190 AUE_VFORK STD { int linux_vfork(void); } 191 AUE_GETRLIMIT STD { int linux_getrlimit(l_uint resource, \ struct l_rlimit *rlim); } 192 AUE_MMAP STD { int linux_mmap2(l_ulong addr, l_ulong len, \ l_ulong prot, l_ulong flags, l_ulong fd, \ l_ulong pgoff); } 193 AUE_TRUNCATE STD { int linux_truncate64(char *path, \ l_loff_t length); } 194 AUE_FTRUNCATE STD { int linux_ftruncate64(l_uint fd, \ l_loff_t length); } 195 AUE_STAT STD { int linux_stat64(char *filename, \ struct l_stat64 *statbuf, l_long flags); } 196 AUE_LSTAT STD { int linux_lstat64(char *filename, \ struct l_stat64 *statbuf, l_long flags); } 197 AUE_FSTAT STD { int linux_fstat64(l_ulong fd, \ struct l_stat64 *statbuf, l_long flags); } 198 AUE_LCHOWN STD { int linux_lchown(char *path, l_uid_t uid, \ l_gid_t gid); } 199 AUE_GETUID STD { int linux_getuid(void); } 200 AUE_GETGID STD { int linux_getgid(void); } 201 AUE_GETEUID NOPROTO { int geteuid(void); } 202 AUE_GETEGID NOPROTO { int getegid(void); } 203 AUE_SETREUID NOPROTO { int setreuid(uid_t ruid, uid_t euid); } 204 AUE_SETREGID NOPROTO { int setregid(gid_t rgid, gid_t egid); } 205 AUE_GETGROUPS STD { int linux_getgroups(l_int gidsetsize, \ l_gid_t *grouplist); } 206 AUE_SETGROUPS STD { int linux_setgroups(l_int gidsetsize, \ l_gid_t *grouplist); } 207 AUE_FCHOWN NODEF fchown fchown fchown_args int 208 AUE_SETRESUID NOPROTO { int setresuid(uid_t ruid, uid_t euid, \ uid_t suid); } 209 AUE_GETRESUID NOPROTO { int getresuid(uid_t *ruid, uid_t *euid, \ uid_t *suid); } 210 AUE_SETRESGID NOPROTO { int setresgid(gid_t rgid, gid_t egid, \ gid_t sgid); } 211 AUE_GETRESGID NOPROTO { int getresgid(gid_t *rgid, gid_t *egid, \ gid_t *sgid); } 212 AUE_CHOWN STD { int linux_chown(char *path, l_uid_t uid, \ l_gid_t gid); } 213 AUE_SETUID NOPROTO { int setuid(uid_t uid); } 214 AUE_SETGID NOPROTO { int setgid(gid_t gid); } 215 AUE_SETFSUID STD { int linux_setfsuid(l_uid_t uid); } 216 AUE_SETFSGID STD { int linux_setfsgid(l_gid_t gid); } 217 AUE_PIVOT_ROOT STD { int linux_pivot_root(char *new_root, \ char *put_old); } 218 AUE_MINCORE STD { int linux_mincore(l_ulong start, \ l_size_t len, u_char *vec); } 219 AUE_MADVISE NOPROTO { int madvise(void *addr, size_t len, \ int behav); } 220 AUE_GETDIRENTRIES STD { int linux_getdents64(l_uint fd, \ void *dirent, l_uint count); } 221 AUE_FCNTL STD { int linux_fcntl64(l_uint fd, l_uint cmd, \ l_ulong arg); } 222 AUE_NULL UNIMPL 223 AUE_NULL UNIMPL 224 AUE_NULL STD { long linux_gettid(void); } 225 AUE_NULL UNIMPL linux_readahead 226 AUE_NULL STD { int linux_setxattr(void); } 227 AUE_NULL STD { int linux_lsetxattr(void); } 228 AUE_NULL STD { int linux_fsetxattr(void); } 229 AUE_NULL STD { int linux_getxattr(void); } 230 AUE_NULL STD { int linux_lgetxattr(void); } 231 AUE_NULL STD { int linux_fgetxattr(void); } 232 AUE_NULL STD { int linux_listxattr(void); } 233 AUE_NULL STD { int linux_llistxattr(void); } 234 AUE_NULL STD { int linux_flistxattr(void); } 235 AUE_NULL STD { int linux_removexattr(void); } 236 AUE_NULL STD { int linux_lremovexattr(void); } 237 AUE_NULL STD { int linux_fremovexattr(void); } 238 AUE_NULL STD { int linux_tkill(int tid, int sig); } 239 AUE_SENDFILE UNIMPL linux_sendfile64 240 AUE_NULL STD { int linux_sys_futex(void *uaddr, int op, uint32_t val, \ struct l_timespec *timeout, uint32_t *uaddr2, uint32_t val3); } 241 AUE_NULL STD { int linux_sched_setaffinity(l_pid_t pid, l_uint len, \ l_ulong *user_mask_ptr); } 242 AUE_NULL STD { int linux_sched_getaffinity(l_pid_t pid, l_uint len, \ l_ulong *user_mask_ptr); } 243 AUE_NULL STD { int linux_set_thread_area(struct l_user_desc *desc); } 244 AUE_NULL STD { int linux_get_thread_area(struct l_user_desc *desc); } 245 AUE_NULL UNIMPL linux_io_setup 246 AUE_NULL UNIMPL linux_io_destroy 247 AUE_NULL UNIMPL linux_io_getevents 248 AUE_NULL UNIMPL linux_io_submit 249 AUE_NULL UNIMPL linux_io_cancel 250 AUE_NULL STD { int linux_fadvise64(void); } 251 AUE_NULL UNIMPL 252 AUE_EXIT STD { int linux_exit_group(int error_code); } 253 AUE_NULL STD { int linux_lookup_dcookie(void); } 254 AUE_NULL STD { int linux_epoll_create(void); } 255 AUE_NULL STD { int linux_epoll_ctl(void); } 256 AUE_NULL STD { int linux_epoll_wait(void); } 257 AUE_NULL STD { int linux_remap_file_pages(void); } 258 AUE_NULL STD { int linux_set_tid_address(int *tidptr); } 259 AUE_NULL STD { int linux_timer_create(clockid_t clock_id, \ struct sigevent *evp, l_timer_t *timerid); } 260 AUE_NULL STD { int linux_timer_settime(l_timer_t timerid, \ const struct itimerspec *new, struct itimerspec *old); } 261 AUE_NULL STD { int linux_timer_gettime(l_timer_t timerid, struct itimerspec *setting); } 262 AUE_NULL STD { int linux_timer_getoverrun(l_timer_t timerid); } 263 AUE_NULL STD { int linux_timer_delete(l_timer_t timerid); } 264 AUE_CLOCK_SETTIME STD { int linux_clock_settime(clockid_t which, struct l_timespec *tp); } 265 AUE_NULL STD { int linux_clock_gettime(clockid_t which, struct l_timespec *tp); } 266 AUE_NULL STD { int linux_clock_getres(clockid_t which, struct l_timespec *tp); } 267 AUE_NULL STD { int linux_clock_nanosleep(clockid_t which, int flags, \ struct l_timespec *rqtp, struct l_timespec *rmtp); } 268 AUE_STATFS STD { int linux_statfs64(char *path, size_t bufsize, struct l_statfs64_buf *buf); } 269 AUE_FSTATFS STD { int linux_fstatfs64(void); } 270 AUE_NULL STD { int linux_tgkill(int tgid, int pid, int sig); } 271 AUE_UTIMES STD { int linux_utimes(char *fname, \ struct l_timeval *tptr); } 272 AUE_NULL STD { int linux_fadvise64_64(void); } 273 AUE_NULL UNIMPL 274 AUE_NULL STD { int linux_mbind(void); } 275 AUE_NULL STD { int linux_get_mempolicy(void); } 276 AUE_NULL STD { int linux_set_mempolicy(void); } 277 AUE_NULL STD { int linux_mq_open(const char *name, int oflag, mode_t mode, \ struct mq_attr *attr); } 278 AUE_NULL STD { int linux_mq_unlink(const char *name); } 279 AUE_NULL STD { int linux_mq_timedsend(l_mqd_t mqd, const char *msg_ptr, \ size_t msg_len, unsigned int msg_prio, const struct \ l_timespec *abs_timeout); } 280 AUE_NULL STD { int linux_mq_timedreceive(l_mqd_t mqd, char *msg_ptr, \ size_t msg_len, unsigned int msg_prio, const struct \ l_timespec *abs_timeout); } 281 AUE_NULL STD { int linux_mq_notify(l_mqd_t mqd, const struct l_timespec *abs_timeout); } 282 AUE_NULL STD { int linux_mq_getsetattr(l_mqd_t mqd, const struct mq_attr *attr, \ struct mq_attr *oattr); } 283 AUE_NULL STD { int linux_kexec_load(void); } 284 AUE_NULL STD { int linux_waitid(void); } 285 AUE_NULL UNIMPL 286 AUE_NULL STD { int linux_add_key(void); } 287 AUE_NULL STD { int linux_request_key(void); } 288 AUE_NULL STD { int linux_keyctl(void); } 289 AUE_NULL STD { int linux_ioprio_set(void); } 290 AUE_NULL STD { int linux_ioprio_get(void); } 291 AUE_NULL STD { int linux_inotify_init(void); } 292 AUE_NULL STD { int linux_inotify_add_watch(void); } 293 AUE_NULL STD { int linux_inotify_rm_watch(void); } 294 AUE_NULL STD { int linux_migrate_pages(void); } 295 AUE_OPEN_RWTC STD { int linux_openat(l_int dfd, const char *filename, \ l_int flags, l_int mode); } 296 AUE_MKDIRAT STD { int linux_mkdirat(l_int dfd, const char *pathname, \ l_int mode); } 297 AUE_MKNODAT STD { int linux_mknodat(l_int dfd, const char *filename, \ l_int mode, l_uint dev); } 298 AUE_FCHOWNAT STD { int linux_fchownat(l_int dfd, const char *filename, \ l_uid16_t uid, l_gid16_t gid, l_int flag); } 299 AUE_FUTIMESAT STD { int linux_futimesat(l_int dfd, char *filename, \ struct l_timeval *utimes); } 300 AUE_FSTATAT STD { int linux_fstatat64(l_int dfd, char *pathname, \ struct l_stat64 *statbuf, l_int flag); } 301 AUE_UNLINKAT STD { int linux_unlinkat(l_int dfd, const char *pathname, \ l_int flag); } 302 AUE_RENAMEAT STD { int linux_renameat(l_int olddfd, const char *oldname, \ l_int newdfd, const char *newname); } 303 AUE_LINKAT STD { int linux_linkat(l_int olddfd, const char *oldname, \ l_int newdfd, const char *newname, l_int flags); } 304 AUE_SYMLINKAT STD { int linux_symlinkat(const char *oldname, l_int newdfd, \ const char *newname); } 305 AUE_READLINKAT STD { int linux_readlinkat(l_int dfd, const char *path, \ char *buf, l_int bufsiz); } 306 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \ l_mode_t mode); } -307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int mode); } +307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode); } 308 AUE_NULL STD { int linux_pselect6(void); } 309 AUE_NULL STD { int linux_ppoll(void); } 310 AUE_NULL STD { int linux_unshare(void); } 311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ l_size_t len); } 312 AUE_NULL STD { int linux_get_robust_list(l_int pid, struct linux_robust_list_head **head, \ l_size_t *len); } 313 AUE_NULL STD { int linux_splice(void); } 314 AUE_NULL STD { int linux_sync_file_range(void); } 315 AUE_NULL STD { int linux_tee(void); } 316 AUE_NULL STD { int linux_vmsplice(void); } diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 8188ccd8ca03..377328971569 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,953 +1,953 @@ $FreeBSD$ ; from: @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; ; System call name/number master file. ; Processed to created init_sysent.c, syscalls.c and syscall.h. ; Columns: number audit type name alt{name,tag,rtyp}/comments ; number system call number, must be in order ; audit the audit event associated with the system call ; A value of AUE_NULL means no auditing, but it also means that ; there is no audit event for the call at this time. For the ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, OBSOL, UNIMPL, COMPAT, COMPAT4, COMPAT6, ; COMPAT7, NODEF, NOARGS, NOPROTO, NOSTD ; The COMPAT* options may be combined with one or more NO* ; options separated by '|' with no spaces (e.g. COMPAT|NOARGS) ; name psuedo-prototype of syscall routine ; If one of the following alts is different, then all appear: ; altname name of system call if different ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL/OBSOL, name continues with comments ; types: ; STD always included ; COMPAT included on COMPAT #ifdef ; COMPAT4 included on COMPAT4 #ifdef (FreeBSD 4 compat) ; COMPAT6 included on COMPAT6 #ifdef (FreeBSD 6 compat) ; COMPAT7 included on COMPAT7 #ifdef (FreeBSD 7 compat) ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only ; NOSTD implemented but as a lkm that can be statically ; compiled in; sysent entry will be filled with lkmressys ; so the SYSCALL_MODULE macro works ; NOARGS same as STD except do not create structure in sys/sysproto.h ; NODEF same as STD except only have the entry in the syscall table ; added. Meaning - do not create structure or function ; prototype in sys/sysproto.h ; NOPROTO same as STD except do not create structure or ; function prototype in sys/sysproto.h. Does add a ; definition to syscall.h besides adding a sysent. ; NOTSTATIC syscall is loadable ; ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master ; #ifdef's, etc. may be included, and are copied to the output files. #include #include #include ; Reserved/unimplemented system calls in the range 0-150 inclusive ; are reserved for use in future Berkeley releases. ; Additional system calls implemented in vendor and other ; redistributions should be placed in the reserved range at the end ; of the current calls. 0 AUE_NULL STD { int nosys(void); } syscall nosys_args int 1 AUE_EXIT STD { void sys_exit(int rval); } exit \ sys_exit_args void 2 AUE_FORK STD { int fork(void); } 3 AUE_NULL STD { ssize_t read(int fd, void *buf, \ size_t nbyte); } 4 AUE_NULL STD { ssize_t write(int fd, const void *buf, \ size_t nbyte); } 5 AUE_OPEN_RWTC STD { int open(char *path, int flags, int mode); } ; XXX should be { int open(const char *path, int flags, ...); } ; but we're not ready for `const' or varargs. ; XXX man page says `mode_t mode'. 6 AUE_CLOSE STD { int close(int fd); } 7 AUE_WAIT4 STD { int wait4(int pid, int *status, \ int options, struct rusage *rusage); } \ wait4 wait_args int 8 AUE_CREAT COMPAT { int creat(char *path, int mode); } 9 AUE_LINK STD { int link(char *path, char *link); } 10 AUE_UNLINK STD { int unlink(char *path); } 11 AUE_NULL OBSOL execv 12 AUE_CHDIR STD { int chdir(char *path); } 13 AUE_FCHDIR STD { int fchdir(int fd); } 14 AUE_MKNOD STD { int mknod(char *path, int mode, int dev); } 15 AUE_CHMOD STD { int chmod(char *path, int mode); } 16 AUE_CHOWN STD { int chown(char *path, int uid, int gid); } 17 AUE_NULL STD { int obreak(char *nsize); } break \ obreak_args int 18 AUE_GETFSSTAT COMPAT4 { int getfsstat(struct ostatfs *buf, \ long bufsize, int flags); } 19 AUE_LSEEK COMPAT { long lseek(int fd, long offset, \ int whence); } 20 AUE_GETPID STD { pid_t getpid(void); } 21 AUE_MOUNT STD { int mount(char *type, char *path, \ int flags, caddr_t data); } ; XXX `path' should have type `const char *' but we're not ready for that. 22 AUE_UMOUNT STD { int unmount(char *path, int flags); } 23 AUE_SETUID STD { int setuid(uid_t uid); } 24 AUE_GETUID STD { uid_t getuid(void); } 25 AUE_GETEUID STD { uid_t geteuid(void); } 26 AUE_PTRACE STD { int ptrace(int req, pid_t pid, \ caddr_t addr, int data); } 27 AUE_RECVMSG STD { int recvmsg(int s, struct msghdr *msg, \ int flags); } 28 AUE_SENDMSG STD { int sendmsg(int s, struct msghdr *msg, \ int flags); } 29 AUE_RECVFROM STD { int recvfrom(int s, caddr_t buf, \ size_t len, int flags, \ struct sockaddr * __restrict from, \ __socklen_t * __restrict fromlenaddr); } 30 AUE_ACCEPT STD { int accept(int s, \ struct sockaddr * __restrict name, \ __socklen_t * __restrict anamelen); } 31 AUE_GETPEERNAME STD { int getpeername(int fdes, \ struct sockaddr * __restrict asa, \ __socklen_t * __restrict alen); } 32 AUE_GETSOCKNAME STD { int getsockname(int fdes, \ struct sockaddr * __restrict asa, \ __socklen_t * __restrict alen); } -33 AUE_ACCESS STD { int access(char *path, int flags); } +33 AUE_ACCESS STD { int access(char *path, int amode); } 34 AUE_CHFLAGS STD { int chflags(char *path, int flags); } 35 AUE_FCHFLAGS STD { int fchflags(int fd, int flags); } 36 AUE_SYNC STD { int sync(void); } 37 AUE_KILL STD { int kill(int pid, int signum); } 38 AUE_STAT COMPAT { int stat(char *path, struct ostat *ub); } 39 AUE_GETPPID STD { pid_t getppid(void); } 40 AUE_LSTAT COMPAT { int lstat(char *path, struct ostat *ub); } 41 AUE_DUP STD { int dup(u_int fd); } 42 AUE_PIPE STD { int pipe(void); } 43 AUE_GETEGID STD { gid_t getegid(void); } 44 AUE_PROFILE STD { int profil(caddr_t samples, size_t size, \ size_t offset, u_int scale); } 45 AUE_KTRACE STD { int ktrace(const char *fname, int ops, \ int facs, int pid); } 46 AUE_SIGACTION COMPAT { int sigaction(int signum, \ struct osigaction *nsa, \ struct osigaction *osa); } 47 AUE_GETGID STD { gid_t getgid(void); } 48 AUE_SIGPROCMASK COMPAT { int sigprocmask(int how, osigset_t mask); } ; XXX note nonstandard (bogus) calling convention - the libc stub passes ; us the mask, not a pointer to it, and we return the old mask as the ; (int) return value. 49 AUE_GETLOGIN STD { int getlogin(char *namebuf, u_int \ namelen); } 50 AUE_SETLOGIN STD { int setlogin(char *namebuf); } 51 AUE_ACCT STD { int acct(char *path); } 52 AUE_SIGPENDING COMPAT { int sigpending(void); } 53 AUE_SIGALTSTACK STD { int sigaltstack(stack_t *ss, \ stack_t *oss); } 54 AUE_IOCTL STD { int ioctl(int fd, u_long com, \ caddr_t data); } 55 AUE_REBOOT STD { int reboot(int opt); } 56 AUE_REVOKE STD { int revoke(char *path); } 57 AUE_SYMLINK STD { int symlink(char *path, char *link); } 58 AUE_READLINK STD { ssize_t readlink(char *path, char *buf, \ size_t count); } 59 AUE_EXECVE STD { int execve(char *fname, char **argv, \ char **envv); } 60 AUE_UMASK STD { int umask(int newmask); } umask umask_args \ int 61 AUE_CHROOT STD { int chroot(char *path); } 62 AUE_FSTAT COMPAT { int fstat(int fd, struct ostat *sb); } 63 AUE_NULL COMPAT { int getkerninfo(int op, char *where, \ size_t *size, int arg); } getkerninfo \ getkerninfo_args int 64 AUE_NULL COMPAT { int getpagesize(void); } getpagesize \ getpagesize_args int 65 AUE_MSYNC STD { int msync(void *addr, size_t len, \ int flags); } 66 AUE_VFORK STD { int vfork(void); } 67 AUE_NULL OBSOL vread 68 AUE_NULL OBSOL vwrite 69 AUE_SBRK STD { int sbrk(int incr); } 70 AUE_SSTK STD { int sstk(int incr); } 71 AUE_MMAP COMPAT { int mmap(void *addr, int len, int prot, \ int flags, int fd, long pos); } 72 AUE_O_VADVISE STD { int ovadvise(int anom); } vadvise \ ovadvise_args int 73 AUE_MUNMAP STD { int munmap(void *addr, size_t len); } 74 AUE_MPROTECT STD { int mprotect(const void *addr, size_t len, \ int prot); } 75 AUE_MADVISE STD { int madvise(void *addr, size_t len, \ int behav); } 76 AUE_NULL OBSOL vhangup 77 AUE_NULL OBSOL vlimit 78 AUE_MINCORE STD { int mincore(const void *addr, size_t len, \ char *vec); } 79 AUE_GETGROUPS STD { int getgroups(u_int gidsetsize, \ gid_t *gidset); } 80 AUE_SETGROUPS STD { int setgroups(u_int gidsetsize, \ gid_t *gidset); } 81 AUE_GETPGRP STD { int getpgrp(void); } 82 AUE_SETPGRP STD { int setpgid(int pid, int pgid); } 83 AUE_SETITIMER STD { int setitimer(u_int which, struct \ itimerval *itv, struct itimerval *oitv); } 84 AUE_WAIT4 COMPAT { int wait(void); } 85 AUE_SWAPON STD { int swapon(char *name); } 86 AUE_GETITIMER STD { int getitimer(u_int which, \ struct itimerval *itv); } 87 AUE_SYSCTL COMPAT { int gethostname(char *hostname, \ u_int len); } gethostname \ gethostname_args int 88 AUE_SYSCTL COMPAT { int sethostname(char *hostname, \ u_int len); } sethostname \ sethostname_args int 89 AUE_GETDTABLESIZE STD { int getdtablesize(void); } 90 AUE_DUP2 STD { int dup2(u_int from, u_int to); } 91 AUE_NULL UNIMPL getdopt 92 AUE_FCNTL STD { int fcntl(int fd, int cmd, long arg); } ; XXX should be { int fcntl(int fd, int cmd, ...); } ; but we're not ready for varargs. 93 AUE_SELECT STD { int select(int nd, fd_set *in, fd_set *ou, \ fd_set *ex, struct timeval *tv); } 94 AUE_NULL UNIMPL setdopt 95 AUE_FSYNC STD { int fsync(int fd); } 96 AUE_SETPRIORITY STD { int setpriority(int which, int who, \ int prio); } 97 AUE_SOCKET STD { int socket(int domain, int type, \ int protocol); } 98 AUE_CONNECT STD { int connect(int s, caddr_t name, \ int namelen); } 99 AUE_ACCEPT COMPAT|NOARGS { int accept(int s, caddr_t name, \ int *anamelen); } accept accept_args int 100 AUE_GETPRIORITY STD { int getpriority(int which, int who); } 101 AUE_SEND COMPAT { int send(int s, caddr_t buf, int len, \ int flags); } 102 AUE_RECV COMPAT { int recv(int s, caddr_t buf, int len, \ int flags); } 103 AUE_SIGRETURN COMPAT { int sigreturn( \ struct osigcontext *sigcntxp); } 104 AUE_BIND STD { int bind(int s, caddr_t name, \ int namelen); } 105 AUE_SETSOCKOPT STD { int setsockopt(int s, int level, int name, \ caddr_t val, int valsize); } 106 AUE_LISTEN STD { int listen(int s, int backlog); } 107 AUE_NULL OBSOL vtimes 108 AUE_NULL COMPAT { int sigvec(int signum, struct sigvec *nsv, \ struct sigvec *osv); } 109 AUE_NULL COMPAT { int sigblock(int mask); } 110 AUE_NULL COMPAT { int sigsetmask(int mask); } 111 AUE_NULL COMPAT { int sigsuspend(osigset_t mask); } ; XXX note nonstandard (bogus) calling convention - the libc stub passes ; us the mask, not a pointer to it. 112 AUE_NULL COMPAT { int sigstack(struct sigstack *nss, \ struct sigstack *oss); } 113 AUE_RECVMSG COMPAT { int recvmsg(int s, struct omsghdr *msg, \ int flags); } 114 AUE_SENDMSG COMPAT { int sendmsg(int s, caddr_t msg, \ int flags); } 115 AUE_NULL OBSOL vtrace 116 AUE_GETTIMEOFDAY STD { int gettimeofday(struct timeval *tp, \ struct timezone *tzp); } 117 AUE_GETRUSAGE STD { int getrusage(int who, \ struct rusage *rusage); } 118 AUE_GETSOCKOPT STD { int getsockopt(int s, int level, int name, \ caddr_t val, int *avalsize); } 119 AUE_NULL UNIMPL resuba (BSD/OS 2.x) 120 AUE_READV STD { int readv(int fd, struct iovec *iovp, \ u_int iovcnt); } 121 AUE_WRITEV STD { int writev(int fd, struct iovec *iovp, \ u_int iovcnt); } 122 AUE_SETTIMEOFDAY STD { int settimeofday(struct timeval *tv, \ struct timezone *tzp); } 123 AUE_FCHOWN STD { int fchown(int fd, int uid, int gid); } 124 AUE_FCHMOD STD { int fchmod(int fd, int mode); } 125 AUE_RECVFROM COMPAT|NOARGS { int recvfrom(int s, caddr_t buf, \ size_t len, int flags, caddr_t from, int \ *fromlenaddr); } recvfrom recvfrom_args \ int 126 AUE_SETREUID STD { int setreuid(int ruid, int euid); } 127 AUE_SETREGID STD { int setregid(int rgid, int egid); } 128 AUE_RENAME STD { int rename(char *from, char *to); } 129 AUE_TRUNCATE COMPAT { int truncate(char *path, long length); } 130 AUE_FTRUNCATE COMPAT { int ftruncate(int fd, long length); } 131 AUE_FLOCK STD { int flock(int fd, int how); } 132 AUE_MKFIFO STD { int mkfifo(char *path, int mode); } 133 AUE_SENDTO STD { int sendto(int s, caddr_t buf, size_t len, \ int flags, caddr_t to, int tolen); } 134 AUE_SHUTDOWN STD { int shutdown(int s, int how); } 135 AUE_SOCKETPAIR STD { int socketpair(int domain, int type, \ int protocol, int *rsv); } 136 AUE_MKDIR STD { int mkdir(char *path, int mode); } 137 AUE_RMDIR STD { int rmdir(char *path); } 138 AUE_UTIMES STD { int utimes(char *path, \ struct timeval *tptr); } 139 AUE_NULL OBSOL 4.2 sigreturn 140 AUE_ADJTIME STD { int adjtime(struct timeval *delta, \ struct timeval *olddelta); } 141 AUE_GETPEERNAME COMPAT { int getpeername(int fdes, caddr_t asa, \ int *alen); } 142 AUE_SYSCTL COMPAT { long gethostid(void); } 143 AUE_SYSCTL COMPAT { int sethostid(long hostid); } 144 AUE_GETRLIMIT COMPAT { int getrlimit(u_int which, struct \ orlimit *rlp); } 145 AUE_SETRLIMIT COMPAT { int setrlimit(u_int which, \ struct orlimit *rlp); } 146 AUE_KILLPG COMPAT { int killpg(int pgid, int signum); } 147 AUE_SETSID STD { int setsid(void); } 148 AUE_QUOTACTL STD { int quotactl(char *path, int cmd, int uid, \ caddr_t arg); } 149 AUE_O_QUOTA COMPAT { int quota(void); } 150 AUE_GETSOCKNAME COMPAT|NOARGS { int getsockname(int fdec, \ caddr_t asa, int *alen); } getsockname \ getsockname_args int ; Syscalls 151-180 inclusive are reserved for vendor-specific ; system calls. (This includes various calls added for compatibity ; with other Unix variants.) ; Some of these calls are now supported by BSD... 151 AUE_NULL UNIMPL sem_lock (BSD/OS 2.x) 152 AUE_NULL UNIMPL sem_wakeup (BSD/OS 2.x) 153 AUE_NULL UNIMPL asyncdaemon (BSD/OS 2.x) ; 154 is initialised by the NLM code, if present. 154 AUE_NULL NOSTD { int nlm_syscall(int debug_level, int grace_period, int addr_count, char **addrs); } ; 155 is initialized by the NFS code, if present. 155 AUE_NFS_SVC NOSTD { int nfssvc(int flag, caddr_t argp); } 156 AUE_GETDIRENTRIES COMPAT { int getdirentries(int fd, char *buf, \ u_int count, long *basep); } 157 AUE_STATFS COMPAT4 { int statfs(char *path, \ struct ostatfs *buf); } 158 AUE_FSTATFS COMPAT4 { int fstatfs(int fd, \ struct ostatfs *buf); } 159 AUE_NULL UNIMPL nosys 160 AUE_LGETFH STD { int lgetfh(char *fname, \ struct fhandle *fhp); } 161 AUE_NFS_GETFH STD { int getfh(char *fname, \ struct fhandle *fhp); } 162 AUE_SYSCTL COMPAT4 { int getdomainname(char *domainname, \ int len); } 163 AUE_SYSCTL COMPAT4 { int setdomainname(char *domainname, \ int len); } 164 AUE_NULL COMPAT4 { int uname(struct utsname *name); } 165 AUE_SYSARCH STD { int sysarch(int op, char *parms); } 166 AUE_RTPRIO STD { int rtprio(int function, pid_t pid, \ struct rtprio *rtp); } 167 AUE_NULL UNIMPL nosys 168 AUE_NULL UNIMPL nosys 169 AUE_SEMSYS NOSTD { int semsys(int which, int a2, int a3, \ int a4, int a5); } ; XXX should be { int semsys(int which, ...); } 170 AUE_MSGSYS NOSTD { int msgsys(int which, int a2, int a3, \ int a4, int a5, int a6); } ; XXX should be { int msgsys(int which, ...); } 171 AUE_SHMSYS NOSTD { int shmsys(int which, int a2, int a3, \ int a4); } ; XXX should be { int shmsys(int which, ...); } 172 AUE_NULL UNIMPL nosys 173 AUE_PREAD STD { ssize_t freebsd6_pread(int fd, void *buf, \ size_t nbyte, int pad, off_t offset); } 174 AUE_PWRITE STD { ssize_t freebsd6_pwrite(int fd, \ const void *buf, \ size_t nbyte, int pad, off_t offset); } 175 AUE_NULL STD { int setfib(int fibnum); } 176 AUE_NTP_ADJTIME STD { int ntp_adjtime(struct timex *tp); } 177 AUE_NULL UNIMPL sfork (BSD/OS 2.x) 178 AUE_NULL UNIMPL getdescriptor (BSD/OS 2.x) 179 AUE_NULL UNIMPL setdescriptor (BSD/OS 2.x) 180 AUE_NULL UNIMPL nosys ; Syscalls 181-199 are used by/reserved for BSD 181 AUE_SETGID STD { int setgid(gid_t gid); } 182 AUE_SETEGID STD { int setegid(gid_t egid); } 183 AUE_SETEUID STD { int seteuid(uid_t euid); } 184 AUE_NULL UNIMPL lfs_bmapv 185 AUE_NULL UNIMPL lfs_markv 186 AUE_NULL UNIMPL lfs_segclean 187 AUE_NULL UNIMPL lfs_segwait 188 AUE_STAT STD { int stat(char *path, struct stat *ub); } 189 AUE_FSTAT STD { int fstat(int fd, struct stat *sb); } 190 AUE_LSTAT STD { int lstat(char *path, struct stat *ub); } 191 AUE_PATHCONF STD { int pathconf(char *path, int name); } 192 AUE_FPATHCONF STD { int fpathconf(int fd, int name); } 193 AUE_NULL UNIMPL nosys 194 AUE_GETRLIMIT STD { int getrlimit(u_int which, \ struct rlimit *rlp); } getrlimit \ __getrlimit_args int 195 AUE_SETRLIMIT STD { int setrlimit(u_int which, \ struct rlimit *rlp); } setrlimit \ __setrlimit_args int 196 AUE_GETDIRENTRIES STD { int getdirentries(int fd, char *buf, \ u_int count, long *basep); } 197 AUE_MMAP STD { caddr_t freebsd6_mmap(caddr_t addr, \ size_t len, int prot, int flags, int fd, \ int pad, off_t pos); } 198 AUE_NULL NOPROTO { int nosys(void); } __syscall \ __syscall_args int 199 AUE_LSEEK STD { off_t freebsd6_lseek(int fd, int pad, \ off_t offset, int whence); } 200 AUE_TRUNCATE STD { int freebsd6_truncate(char *path, int pad, \ off_t length); } 201 AUE_FTRUNCATE STD { int freebsd6_ftruncate(int fd, int pad, \ off_t length); } 202 AUE_SYSCTL STD { int __sysctl(int *name, u_int namelen, \ void *old, size_t *oldlenp, void *new, \ size_t newlen); } __sysctl sysctl_args int 203 AUE_MLOCK STD { int mlock(const void *addr, size_t len); } 204 AUE_MUNLOCK STD { int munlock(const void *addr, size_t len); } 205 AUE_UNDELETE STD { int undelete(char *path); } 206 AUE_FUTIMES STD { int futimes(int fd, struct timeval *tptr); } 207 AUE_GETPGID STD { int getpgid(pid_t pid); } 208 AUE_NULL UNIMPL newreboot (NetBSD) 209 AUE_POLL STD { int poll(struct pollfd *fds, u_int nfds, \ int timeout); } ; ; The following are reserved for loadable syscalls ; 210 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 211 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 212 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 213 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 214 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 215 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 216 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 217 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 218 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int 219 AUE_NULL NODEF|NOTSTATIC lkmnosys lkmnosys nosys_args int ; ; The following were introduced with NetBSD/4.4Lite-2 220 AUE_SEMCTL COMPAT7|NOSTD { int __semctl(int semid, int semnum, \ int cmd, union semun_old *arg); } 221 AUE_SEMGET NOSTD { int semget(key_t key, int nsems, \ int semflg); } 222 AUE_SEMOP NOSTD { int semop(int semid, struct sembuf *sops, \ size_t nsops); } 223 AUE_NULL UNIMPL semconfig 224 AUE_MSGCTL COMPAT7|NOSTD { int msgctl(int msqid, int cmd, \ struct msqid_ds_old *buf); } 225 AUE_MSGGET NOSTD { int msgget(key_t key, int msgflg); } 226 AUE_MSGSND NOSTD { int msgsnd(int msqid, const void *msgp, \ size_t msgsz, int msgflg); } 227 AUE_MSGRCV NOSTD { int msgrcv(int msqid, void *msgp, \ size_t msgsz, long msgtyp, int msgflg); } 228 AUE_SHMAT NOSTD { int shmat(int shmid, const void *shmaddr, \ int shmflg); } 229 AUE_SHMCTL COMPAT7|NOSTD { int shmctl(int shmid, int cmd, \ struct shmid_ds_old *buf); } 230 AUE_SHMDT NOSTD { int shmdt(const void *shmaddr); } 231 AUE_SHMGET NOSTD { int shmget(key_t key, size_t size, \ int shmflg); } ; 232 AUE_NULL STD { int clock_gettime(clockid_t clock_id, \ struct timespec *tp); } 233 AUE_CLOCK_SETTIME STD { int clock_settime( \ clockid_t clock_id, \ const struct timespec *tp); } 234 AUE_NULL STD { int clock_getres(clockid_t clock_id, \ struct timespec *tp); } 235 AUE_NULL STD { int ktimer_create(clockid_t clock_id, \ struct sigevent *evp, int *timerid); } 236 AUE_NULL STD { int ktimer_delete(int timerid); } 237 AUE_NULL STD { int ktimer_settime(int timerid, int flags, \ const struct itimerspec *value, \ struct itimerspec *ovalue); } 238 AUE_NULL STD { int ktimer_gettime(int timerid, struct \ itimerspec *value); } 239 AUE_NULL STD { int ktimer_getoverrun(int timerid); } 240 AUE_NULL STD { int nanosleep(const struct timespec *rqtp, \ struct timespec *rmtp); } 241 AUE_NULL UNIMPL nosys 242 AUE_NULL UNIMPL nosys 243 AUE_NULL UNIMPL nosys 244 AUE_NULL UNIMPL nosys 245 AUE_NULL UNIMPL nosys 246 AUE_NULL UNIMPL nosys 247 AUE_NULL UNIMPL nosys 248 AUE_NULL STD { int ntp_gettime(struct ntptimeval *ntvp); } 249 AUE_NULL UNIMPL nosys ; syscall numbers initially used in OpenBSD 250 AUE_MINHERIT STD { int minherit(void *addr, size_t len, \ int inherit); } 251 AUE_RFORK STD { int rfork(int flags); } 252 AUE_POLL STD { int openbsd_poll(struct pollfd *fds, \ u_int nfds, int timeout); } 253 AUE_ISSETUGID STD { int issetugid(void); } 254 AUE_LCHOWN STD { int lchown(char *path, int uid, int gid); } 255 AUE_NULL NOSTD { int aio_read(struct aiocb *aiocbp); } 256 AUE_NULL NOSTD { int aio_write(struct aiocb *aiocbp); } 257 AUE_NULL NOSTD { int lio_listio(int mode, \ struct aiocb * const *acb_list, \ int nent, struct sigevent *sig); } 258 AUE_NULL UNIMPL nosys 259 AUE_NULL UNIMPL nosys 260 AUE_NULL UNIMPL nosys 261 AUE_NULL UNIMPL nosys 262 AUE_NULL UNIMPL nosys 263 AUE_NULL UNIMPL nosys 264 AUE_NULL UNIMPL nosys 265 AUE_NULL UNIMPL nosys 266 AUE_NULL UNIMPL nosys 267 AUE_NULL UNIMPL nosys 268 AUE_NULL UNIMPL nosys 269 AUE_NULL UNIMPL nosys 270 AUE_NULL UNIMPL nosys 271 AUE_NULL UNIMPL nosys 272 AUE_O_GETDENTS STD { int getdents(int fd, char *buf, \ size_t count); } 273 AUE_NULL UNIMPL nosys 274 AUE_LCHMOD STD { int lchmod(char *path, mode_t mode); } 275 AUE_LCHOWN NOPROTO { int lchown(char *path, uid_t uid, \ gid_t gid); } netbsd_lchown lchown_args \ int 276 AUE_LUTIMES STD { int lutimes(char *path, \ struct timeval *tptr); } 277 AUE_MSYNC NOPROTO { int msync(void *addr, size_t len, \ int flags); } netbsd_msync msync_args int 278 AUE_STAT STD { int nstat(char *path, struct nstat *ub); } 279 AUE_FSTAT STD { int nfstat(int fd, struct nstat *sb); } 280 AUE_LSTAT STD { int nlstat(char *path, struct nstat *ub); } 281 AUE_NULL UNIMPL nosys 282 AUE_NULL UNIMPL nosys 283 AUE_NULL UNIMPL nosys 284 AUE_NULL UNIMPL nosys 285 AUE_NULL UNIMPL nosys 286 AUE_NULL UNIMPL nosys 287 AUE_NULL UNIMPL nosys 288 AUE_NULL UNIMPL nosys ; 289 and 290 from NetBSD (OpenBSD: 267 and 268) 289 AUE_PREADV STD { ssize_t preadv(int fd, struct iovec *iovp, \ u_int iovcnt, off_t offset); } 290 AUE_PWRITEV STD { ssize_t pwritev(int fd, struct iovec *iovp, \ u_int iovcnt, off_t offset); } 291 AUE_NULL UNIMPL nosys 292 AUE_NULL UNIMPL nosys 293 AUE_NULL UNIMPL nosys 294 AUE_NULL UNIMPL nosys 295 AUE_NULL UNIMPL nosys 296 AUE_NULL UNIMPL nosys ; XXX 297 is 300 in NetBSD 297 AUE_FHSTATFS COMPAT4 { int fhstatfs( \ const struct fhandle *u_fhp, \ struct ostatfs *buf); } 298 AUE_FHOPEN STD { int fhopen(const struct fhandle *u_fhp, \ int flags); } 299 AUE_FHSTAT STD { int fhstat(const struct fhandle *u_fhp, \ struct stat *sb); } ; syscall numbers for FreeBSD 300 AUE_NULL STD { int modnext(int modid); } 301 AUE_NULL STD { int modstat(int modid, \ struct module_stat *stat); } 302 AUE_NULL STD { int modfnext(int modid); } 303 AUE_NULL STD { int modfind(const char *name); } 304 AUE_MODLOAD STD { int kldload(const char *file); } 305 AUE_MODUNLOAD STD { int kldunload(int fileid); } 306 AUE_NULL STD { int kldfind(const char *file); } 307 AUE_NULL STD { int kldnext(int fileid); } 308 AUE_NULL STD { int kldstat(int fileid, struct \ kld_file_stat* stat); } 309 AUE_NULL STD { int kldfirstmod(int fileid); } 310 AUE_GETSID STD { int getsid(pid_t pid); } 311 AUE_SETRESUID STD { int setresuid(uid_t ruid, uid_t euid, \ uid_t suid); } 312 AUE_SETRESGID STD { int setresgid(gid_t rgid, gid_t egid, \ gid_t sgid); } 313 AUE_NULL OBSOL signanosleep 314 AUE_NULL NOSTD { int aio_return(struct aiocb *aiocbp); } 315 AUE_NULL NOSTD { int aio_suspend( \ struct aiocb * const * aiocbp, int nent, \ const struct timespec *timeout); } 316 AUE_NULL NOSTD { int aio_cancel(int fd, \ struct aiocb *aiocbp); } 317 AUE_NULL NOSTD { int aio_error(struct aiocb *aiocbp); } 318 AUE_NULL NOSTD { int oaio_read(struct oaiocb *aiocbp); } 319 AUE_NULL NOSTD { int oaio_write(struct oaiocb *aiocbp); } 320 AUE_NULL NOSTD { int olio_listio(int mode, \ struct oaiocb * const *acb_list, \ int nent, struct osigevent *sig); } 321 AUE_NULL STD { int yield(void); } 322 AUE_NULL OBSOL thr_sleep 323 AUE_NULL OBSOL thr_wakeup 324 AUE_MLOCKALL STD { int mlockall(int how); } 325 AUE_MUNLOCKALL STD { int munlockall(void); } 326 AUE_GETCWD STD { int __getcwd(u_char *buf, u_int buflen); } 327 AUE_NULL STD { int sched_setparam (pid_t pid, \ const struct sched_param *param); } 328 AUE_NULL STD { int sched_getparam (pid_t pid, struct \ sched_param *param); } 329 AUE_NULL STD { int sched_setscheduler (pid_t pid, int \ policy, const struct sched_param \ *param); } 330 AUE_NULL STD { int sched_getscheduler (pid_t pid); } 331 AUE_NULL STD { int sched_yield (void); } 332 AUE_NULL STD { int sched_get_priority_max (int policy); } 333 AUE_NULL STD { int sched_get_priority_min (int policy); } 334 AUE_NULL STD { int sched_rr_get_interval (pid_t pid, \ struct timespec *interval); } 335 AUE_NULL STD { int utrace(const void *addr, size_t len); } 336 AUE_SENDFILE COMPAT4 { int sendfile(int fd, int s, \ off_t offset, size_t nbytes, \ struct sf_hdtr *hdtr, off_t *sbytes, \ int flags); } 337 AUE_NULL STD { int kldsym(int fileid, int cmd, \ void *data); } 338 AUE_JAIL STD { int jail(struct jail *jail); } 339 AUE_NULL NOSTD|NOTSTATIC { int nnpfs_syscall(int operation, \ char *a_pathP, int a_opcode, \ void *a_paramsP, int a_followSymlinks); } 340 AUE_SIGPROCMASK STD { int sigprocmask(int how, \ const sigset_t *set, sigset_t *oset); } 341 AUE_SIGSUSPEND STD { int sigsuspend(const sigset_t *sigmask); } 342 AUE_SIGACTION COMPAT4 { int sigaction(int sig, const \ struct sigaction *act, \ struct sigaction *oact); } 343 AUE_SIGPENDING STD { int sigpending(sigset_t *set); } 344 AUE_SIGRETURN COMPAT4 { int sigreturn( \ const struct ucontext4 *sigcntxp); } 345 AUE_SIGWAIT STD { int sigtimedwait(const sigset_t *set, \ siginfo_t *info, \ const struct timespec *timeout); } 346 AUE_NULL STD { int sigwaitinfo(const sigset_t *set, \ siginfo_t *info); } 347 AUE_NULL STD { int __acl_get_file(const char *path, \ acl_type_t type, struct acl *aclp); } 348 AUE_NULL STD { int __acl_set_file(const char *path, \ acl_type_t type, struct acl *aclp); } 349 AUE_NULL STD { int __acl_get_fd(int filedes, \ acl_type_t type, struct acl *aclp); } 350 AUE_NULL STD { int __acl_set_fd(int filedes, \ acl_type_t type, struct acl *aclp); } 351 AUE_NULL STD { int __acl_delete_file(const char *path, \ acl_type_t type); } 352 AUE_NULL STD { int __acl_delete_fd(int filedes, \ acl_type_t type); } 353 AUE_NULL STD { int __acl_aclcheck_file(const char *path, \ acl_type_t type, struct acl *aclp); } 354 AUE_NULL STD { int __acl_aclcheck_fd(int filedes, \ acl_type_t type, struct acl *aclp); } 355 AUE_EXTATTRCTL STD { int extattrctl(const char *path, int cmd, \ const char *filename, int attrnamespace, \ const char *attrname); } 356 AUE_EXTATTR_SET_FILE STD { int extattr_set_file( \ const char *path, int attrnamespace, \ const char *attrname, void *data, \ size_t nbytes); } 357 AUE_EXTATTR_GET_FILE STD { ssize_t extattr_get_file( \ const char *path, int attrnamespace, \ const char *attrname, void *data, \ size_t nbytes); } 358 AUE_EXTATTR_DELETE_FILE STD { int extattr_delete_file(const char *path, \ int attrnamespace, \ const char *attrname); } 359 AUE_NULL NOSTD { int aio_waitcomplete( \ struct aiocb **aiocbp, \ struct timespec *timeout); } 360 AUE_GETRESUID STD { int getresuid(uid_t *ruid, uid_t *euid, \ uid_t *suid); } 361 AUE_GETRESGID STD { int getresgid(gid_t *rgid, gid_t *egid, \ gid_t *sgid); } 362 AUE_KQUEUE STD { int kqueue(void); } 363 AUE_NULL STD { int kevent(int fd, \ struct kevent *changelist, int nchanges, \ struct kevent *eventlist, int nevents, \ const struct timespec *timeout); } 364 AUE_NULL UNIMPL __cap_get_proc 365 AUE_NULL UNIMPL __cap_set_proc 366 AUE_NULL UNIMPL __cap_get_fd 367 AUE_NULL UNIMPL __cap_get_file 368 AUE_NULL UNIMPL __cap_set_fd 369 AUE_NULL UNIMPL __cap_set_file 370 AUE_NULL UNIMPL nosys 371 AUE_EXTATTR_SET_FD STD { int extattr_set_fd(int fd, \ int attrnamespace, const char *attrname, \ void *data, size_t nbytes); } 372 AUE_EXTATTR_GET_FD STD { ssize_t extattr_get_fd(int fd, \ int attrnamespace, const char *attrname, \ void *data, size_t nbytes); } 373 AUE_EXTATTR_DELETE_FD STD { int extattr_delete_fd(int fd, \ int attrnamespace, \ const char *attrname); } 374 AUE_NULL STD { int __setugid(int flag); } 375 AUE_NULL UNIMPL nfsclnt -376 AUE_EACCESS STD { int eaccess(char *path, int flags); } +376 AUE_EACCESS STD { int eaccess(char *path, int amode); } 377 AUE_NULL NOSTD|NOTSTATIC { int afs3_syscall(long syscall, \ long parm1, long parm2, long parm3, \ long parm4, long parm5, long parm6); } 378 AUE_NMOUNT STD { int nmount(struct iovec *iovp, \ unsigned int iovcnt, int flags); } 379 AUE_NULL UNIMPL kse_exit 380 AUE_NULL UNIMPL kse_wakeup 381 AUE_NULL UNIMPL kse_create 382 AUE_NULL UNIMPL kse_thr_interrupt 383 AUE_NULL UNIMPL kse_release 384 AUE_NULL STD { int __mac_get_proc(struct mac *mac_p); } 385 AUE_NULL STD { int __mac_set_proc(struct mac *mac_p); } 386 AUE_NULL STD { int __mac_get_fd(int fd, \ struct mac *mac_p); } 387 AUE_NULL STD { int __mac_get_file(const char *path_p, \ struct mac *mac_p); } 388 AUE_NULL STD { int __mac_set_fd(int fd, \ struct mac *mac_p); } 389 AUE_NULL STD { int __mac_set_file(const char *path_p, \ struct mac *mac_p); } 390 AUE_NULL STD { int kenv(int what, const char *name, \ char *value, int len); } 391 AUE_LCHFLAGS STD { int lchflags(const char *path, int flags); } 392 AUE_NULL STD { int uuidgen(struct uuid *store, \ int count); } 393 AUE_SENDFILE STD { int sendfile(int fd, int s, off_t offset, \ size_t nbytes, struct sf_hdtr *hdtr, \ off_t *sbytes, int flags); } 394 AUE_NULL STD { int mac_syscall(const char *policy, \ int call, void *arg); } 395 AUE_GETFSSTAT STD { int getfsstat(struct statfs *buf, \ long bufsize, int flags); } 396 AUE_STATFS STD { int statfs(char *path, \ struct statfs *buf); } 397 AUE_FSTATFS STD { int fstatfs(int fd, struct statfs *buf); } 398 AUE_FHSTATFS STD { int fhstatfs(const struct fhandle *u_fhp, \ struct statfs *buf); } 399 AUE_NULL UNIMPL nosys 400 AUE_NULL NOSTD { int ksem_close(semid_t id); } 401 AUE_NULL NOSTD { int ksem_post(semid_t id); } 402 AUE_NULL NOSTD { int ksem_wait(semid_t id); } 403 AUE_NULL NOSTD { int ksem_trywait(semid_t id); } 404 AUE_NULL NOSTD { int ksem_init(semid_t *idp, \ unsigned int value); } 405 AUE_NULL NOSTD { int ksem_open(semid_t *idp, \ const char *name, int oflag, \ mode_t mode, unsigned int value); } 406 AUE_NULL NOSTD { int ksem_unlink(const char *name); } 407 AUE_NULL NOSTD { int ksem_getvalue(semid_t id, int *val); } 408 AUE_NULL NOSTD { int ksem_destroy(semid_t id); } 409 AUE_NULL STD { int __mac_get_pid(pid_t pid, \ struct mac *mac_p); } 410 AUE_NULL STD { int __mac_get_link(const char *path_p, \ struct mac *mac_p); } 411 AUE_NULL STD { int __mac_set_link(const char *path_p, \ struct mac *mac_p); } 412 AUE_EXTATTR_SET_LINK STD { int extattr_set_link( \ const char *path, int attrnamespace, \ const char *attrname, void *data, \ size_t nbytes); } 413 AUE_EXTATTR_GET_LINK STD { ssize_t extattr_get_link( \ const char *path, int attrnamespace, \ const char *attrname, void *data, \ size_t nbytes); } 414 AUE_EXTATTR_DELETE_LINK STD { int extattr_delete_link( \ const char *path, int attrnamespace, \ const char *attrname); } 415 AUE_NULL STD { int __mac_execve(char *fname, char **argv, \ char **envv, struct mac *mac_p); } 416 AUE_SIGACTION STD { int sigaction(int sig, \ const struct sigaction *act, \ struct sigaction *oact); } 417 AUE_SIGRETURN STD { int sigreturn( \ const struct __ucontext *sigcntxp); } 418 AUE_NULL UNIMPL __xstat 419 AUE_NULL UNIMPL __xfstat 420 AUE_NULL UNIMPL __xlstat 421 AUE_NULL STD { int getcontext(struct __ucontext *ucp); } 422 AUE_NULL STD { int setcontext( \ const struct __ucontext *ucp); } 423 AUE_NULL STD { int swapcontext(struct __ucontext *oucp, \ const struct __ucontext *ucp); } 424 AUE_SWAPOFF STD { int swapoff(const char *name); } 425 AUE_NULL STD { int __acl_get_link(const char *path, \ acl_type_t type, struct acl *aclp); } 426 AUE_NULL STD { int __acl_set_link(const char *path, \ acl_type_t type, struct acl *aclp); } 427 AUE_NULL STD { int __acl_delete_link(const char *path, \ acl_type_t type); } 428 AUE_NULL STD { int __acl_aclcheck_link(const char *path, \ acl_type_t type, struct acl *aclp); } 429 AUE_SIGWAIT STD { int sigwait(const sigset_t *set, \ int *sig); } 430 AUE_NULL STD { int thr_create(ucontext_t *ctx, long *id, \ int flags); } 431 AUE_NULL STD { void thr_exit(long *state); } 432 AUE_NULL STD { int thr_self(long *id); } 433 AUE_NULL STD { int thr_kill(long id, int sig); } 434 AUE_NULL STD { int _umtx_lock(struct umtx *umtx); } 435 AUE_NULL STD { int _umtx_unlock(struct umtx *umtx); } 436 AUE_NULL STD { int jail_attach(int jid); } 437 AUE_EXTATTR_LIST_FD STD { ssize_t extattr_list_fd(int fd, \ int attrnamespace, void *data, \ size_t nbytes); } 438 AUE_EXTATTR_LIST_FILE STD { ssize_t extattr_list_file( \ const char *path, int attrnamespace, \ void *data, size_t nbytes); } 439 AUE_EXTATTR_LIST_LINK STD { ssize_t extattr_list_link( \ const char *path, int attrnamespace, \ void *data, size_t nbytes); } 440 AUE_NULL UNIMPL kse_switchin 441 AUE_NULL NOSTD { int ksem_timedwait(semid_t id, \ const struct timespec *abstime); } 442 AUE_NULL STD { int thr_suspend( \ const struct timespec *timeout); } 443 AUE_NULL STD { int thr_wake(long id); } 444 AUE_MODUNLOAD STD { int kldunloadf(int fileid, int flags); } 445 AUE_AUDIT STD { int audit(const void *record, \ u_int length); } 446 AUE_AUDITON STD { int auditon(int cmd, void *data, \ u_int length); } 447 AUE_GETAUID STD { int getauid(uid_t *auid); } 448 AUE_SETAUID STD { int setauid(uid_t *auid); } 449 AUE_GETAUDIT STD { int getaudit(struct auditinfo *auditinfo); } 450 AUE_SETAUDIT STD { int setaudit(struct auditinfo *auditinfo); } 451 AUE_GETAUDIT_ADDR STD { int getaudit_addr( \ struct auditinfo_addr *auditinfo_addr, \ u_int length); } 452 AUE_SETAUDIT_ADDR STD { int setaudit_addr( \ struct auditinfo_addr *auditinfo_addr, \ u_int length); } 453 AUE_AUDITCTL STD { int auditctl(char *path); } 454 AUE_NULL STD { int _umtx_op(void *obj, int op, \ u_long val, void *uaddr1, void *uaddr2); } 455 AUE_NULL STD { int thr_new(struct thr_param *param, \ int param_size); } 456 AUE_NULL STD { int sigqueue(pid_t pid, int signum, void *value); } 457 AUE_NULL NOSTD { int kmq_open(const char *path, int flags, \ mode_t mode, const struct mq_attr *attr); } 458 AUE_NULL NOSTD { int kmq_setattr(int mqd, \ const struct mq_attr *attr, \ struct mq_attr *oattr); } 459 AUE_NULL NOSTD { int kmq_timedreceive(int mqd, \ char *msg_ptr, size_t msg_len, \ unsigned *msg_prio, \ const struct timespec *abs_timeout); } 460 AUE_NULL NOSTD { int kmq_timedsend(int mqd, \ const char *msg_ptr, size_t msg_len,\ unsigned msg_prio, \ const struct timespec *abs_timeout);} 461 AUE_NULL NOSTD { int kmq_notify(int mqd, \ const struct sigevent *sigev); } 462 AUE_NULL NOSTD { int kmq_unlink(const char *path); } 463 AUE_NULL STD { int abort2(const char *why, int nargs, void **args); } 464 AUE_NULL STD { int thr_set_name(long id, const char *name); } 465 AUE_NULL NOSTD { int aio_fsync(int op, struct aiocb *aiocbp); } 466 AUE_RTPRIO STD { int rtprio_thread(int function, \ lwpid_t lwpid, struct rtprio *rtp); } 467 AUE_NULL UNIMPL nosys 468 AUE_NULL UNIMPL nosys 469 AUE_NULL UNIMPL __getpath_fromfd 470 AUE_NULL UNIMPL __getpath_fromaddr 471 AUE_NULL STD { int sctp_peeloff(int sd, uint32_t name); } 472 AUE_NULL STD { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \ caddr_t to, __socklen_t tolen, \ struct sctp_sndrcvinfo *sinfo, int flags); } 473 AUE_NULL STD { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \ caddr_t to, __socklen_t tolen, \ struct sctp_sndrcvinfo *sinfo, int flags); } 474 AUE_NULL STD { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \ struct sockaddr * from, __socklen_t *fromlenaddr, \ struct sctp_sndrcvinfo *sinfo, int *msg_flags); } 475 AUE_PREAD STD { ssize_t pread(int fd, void *buf, \ size_t nbyte, off_t offset); } 476 AUE_PWRITE STD { ssize_t pwrite(int fd, const void *buf, \ size_t nbyte, off_t offset); } 477 AUE_MMAP STD { caddr_t mmap(caddr_t addr, size_t len, \ int prot, int flags, int fd, off_t pos); } 478 AUE_LSEEK STD { off_t lseek(int fd, off_t offset, \ int whence); } 479 AUE_TRUNCATE STD { int truncate(char *path, off_t length); } 480 AUE_FTRUNCATE STD { int ftruncate(int fd, off_t length); } 481 AUE_KILL STD { int thr_kill2(pid_t pid, long id, int sig); } 482 AUE_SHMOPEN STD { int shm_open(const char *path, int flags, \ mode_t mode); } 483 AUE_SHMUNLINK STD { int shm_unlink(const char *path); } 484 AUE_NULL STD { int cpuset(cpusetid_t *setid); } 485 AUE_NULL STD { int cpuset_setid(cpuwhich_t which, id_t id, \ cpusetid_t setid); } 486 AUE_NULL STD { int cpuset_getid(cpulevel_t level, \ cpuwhich_t which, id_t id, \ cpusetid_t *setid); } 487 AUE_NULL STD { int cpuset_getaffinity(cpulevel_t level, \ cpuwhich_t which, id_t id, size_t cpusetsize, \ cpuset_t *mask); } 488 AUE_NULL STD { int cpuset_setaffinity(cpulevel_t level, \ cpuwhich_t which, id_t id, size_t cpusetsize, \ const cpuset_t *mask); } -489 AUE_FACCESSAT STD { int faccessat(int fd, char *path, int mode, \ +489 AUE_FACCESSAT STD { int faccessat(int fd, char *path, int amode, \ int flag); } 490 AUE_FCHMODAT STD { int fchmodat(int fd, char *path, mode_t mode, \ int flag); } 491 AUE_FCHOWNAT STD { int fchownat(int fd, char *path, uid_t uid, \ gid_t gid, int flag); } 492 AUE_FEXECVE STD { int fexecve(int fd, char **argv, \ char **envv); } 493 AUE_FSTATAT STD { int fstatat(int fd, char *path, \ struct stat *buf, int flag); } 494 AUE_FUTIMESAT STD { int futimesat(int fd, char *path, \ struct timeval *times); } 495 AUE_LINKAT STD { int linkat(int fd1, char *path1, int fd2, \ char *path2, int flag); } 496 AUE_MKDIRAT STD { int mkdirat(int fd, char *path, mode_t mode); } 497 AUE_MKFIFOAT STD { int mkfifoat(int fd, char *path, mode_t mode); } 498 AUE_MKNODAT STD { int mknodat(int fd, char *path, mode_t mode, \ dev_t dev); } ; XXX: see the comment for open 499 AUE_OPENAT_RWTC STD { int openat(int fd, char *path, int flag, \ mode_t mode); } 500 AUE_READLINKAT STD { int readlinkat(int fd, char *path, char *buf, \ size_t bufsize); } 501 AUE_RENAMEAT STD { int renameat(int oldfd, char *old, int newfd, \ char *new); } 502 AUE_SYMLINKAT STD { int symlinkat(char *path1, int fd, \ char *path2); } 503 AUE_UNLINKAT STD { int unlinkat(int fd, char *path, int flag); } 504 AUE_POSIX_OPENPT STD { int posix_openpt(int flags); } ; 505 is initialised by the kgssapi code, if present. 505 AUE_NULL NOSTD { int gssd_syscall(char *path); } 506 AUE_NULL STD { int jail_get(struct iovec *iovp, \ unsigned int iovcnt, int flags); } 507 AUE_NULL STD { int jail_set(struct iovec *iovp, \ unsigned int iovcnt, int flags); } 508 AUE_NULL STD { int jail_remove(int jid); } 509 AUE_CLOSEFROM STD { int closefrom(int lowfd); } 510 AUE_SEMCTL NOSTD { int __semctl(int semid, int semnum, \ int cmd, union semun *arg); } 511 AUE_MSGCTL NOSTD { int msgctl(int msqid, int cmd, \ struct msqid_ds *buf); } 512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \ struct shmid_ds *buf); } 513 AUE_LPATHCONF STD { int lpathconf(char *path, int name); } 514 AUE_CAP_NEW STD { int cap_new(int fd, u_int64_t rights); } 515 AUE_CAP_GETRIGHTS STD { int cap_getrights(int fd, \ u_int64_t *rightsp); } 516 AUE_CAP_ENTER STD { int cap_enter(void); } 517 AUE_CAP_GETMODE STD { int cap_getmode(u_int *modep); } 518 AUE_PDFORK STD { int pdfork(int *fdp, int flags); } 519 AUE_PDKILL STD { int pdkill(int fd, int signum); } 520 AUE_PDGETPID STD { int pdgetpid(int fd, pid_t *pidp); } 521 AUE_PDWAIT UNIMPL pdwait4 522 AUE_SELECT STD { int pselect(int nd, fd_set *in, \ fd_set *ou, fd_set *ex, \ const struct timespec *ts, \ const sigset_t *sm); } 523 AUE_NULL STD { int getloginclass(char *namebuf, \ size_t namelen); } 524 AUE_NULL STD { int setloginclass(const char *namebuf); } 525 AUE_NULL STD { int rctl_get_racct(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 526 AUE_NULL STD { int rctl_get_rules(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 527 AUE_NULL STD { int rctl_get_limits(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 528 AUE_NULL STD { int rctl_add_rule(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 529 AUE_NULL STD { int rctl_remove_rule(const void *inbufp, \ size_t inbuflen, void *outbufp, \ size_t outbuflen); } 530 AUE_NULL STD { int posix_fallocate(int fd, \ off_t offset, off_t len); } 531 AUE_NULL STD { int posix_fadvise(int fd, off_t offset, \ off_t len, int advice); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 3356666af666..fe012d5a800a 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4986 +1,4986 @@ /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 */ #include __FBSDID("$FreeBSD$"); #include "opt_capsicum.h" #include "opt_compat.h" #include "opt_kdtrace.h" #include "opt_ktrace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef KTRACE #include #endif #include #include #include #include #include #include #include static MALLOC_DEFINE(M_FADVISE, "fadvise", "posix_fadvise(2) information"); SDT_PROVIDER_DEFINE(vfs); SDT_PROBE_DEFINE(vfs, , stat, mode, mode); SDT_PROBE_ARGTYPE(vfs, , stat, mode, 0, "char *"); SDT_PROBE_ARGTYPE(vfs, , stat, mode, 1, "int"); SDT_PROBE_DEFINE(vfs, , stat, reg, reg); SDT_PROBE_ARGTYPE(vfs, , stat, reg, 0, "char *"); SDT_PROBE_ARGTYPE(vfs, , stat, reg, 1, "int"); static int chroot_refuse_vdir_fds(struct filedesc *fdp); static int getutimes(const struct timeval *, enum uio_seg, struct timespec *); static int setfflags(struct thread *td, struct vnode *, int); static int setutimes(struct thread *td, struct vnode *, const struct timespec *, int, int); static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred, struct thread *td); /* * The module initialization routine for POSIX asynchronous I/O will * set this to the version of AIO that it implements. (Zero means * that it is not implemented.) This value is used here by pathconf() * and in kern_descrip.c by fpathconf(). */ int async_io_version; #ifdef DEBUG static int syncprt = 0; SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, ""); #endif /* * Sync each mounted filesystem. */ #ifndef _SYS_SYSPROTO_H_ struct sync_args { int dummy; }; #endif /* ARGSUSED */ int sys_sync(td, uap) struct thread *td; struct sync_args *uap; { struct mount *mp, *nmp; int vfslocked; mtx_lock(&mountlist_mtx); for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } vfslocked = VFS_LOCK_GIANT(mp); if ((mp->mnt_flag & MNT_RDONLY) == 0 && vn_start_write(NULL, &mp, V_NOWAIT) == 0) { MNT_ILOCK(mp); mp->mnt_noasync++; mp->mnt_kern_flag &= ~MNTK_ASYNC; MNT_IUNLOCK(mp); vfs_msync(mp, MNT_NOWAIT); VFS_SYNC(mp, MNT_NOWAIT); MNT_ILOCK(mp); mp->mnt_noasync--; if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0) mp->mnt_kern_flag |= MNTK_ASYNC; MNT_IUNLOCK(mp); vn_finished_write(mp); } VFS_UNLOCK_GIANT(vfslocked); mtx_lock(&mountlist_mtx); nmp = TAILQ_NEXT(mp, mnt_list); vfs_unbusy(mp); } mtx_unlock(&mountlist_mtx); return (0); } /* * Change filesystem quotas. */ #ifndef _SYS_SYSPROTO_H_ struct quotactl_args { char *path; int cmd; int uid; caddr_t arg; }; #endif int sys_quotactl(td, uap) struct thread *td; register struct quotactl_args /* { char *path; int cmd; int uid; caddr_t arg; } */ *uap; { struct mount *mp; int vfslocked; int error; struct nameidata nd; AUDIT_ARG_CMD(uap->cmd); AUDIT_ARG_UID(uap->uid); if (!prison_allow(td->td_ucred, PR_ALLOW_QUOTAS)) return (EPERM); NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, UIO_USERSPACE, uap->path, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); mp = nd.ni_vp->v_mount; vfs_ref(mp); vput(nd.ni_vp); error = vfs_busy(mp, 0); vfs_rel(mp); if (error) { VFS_UNLOCK_GIANT(vfslocked); return (error); } error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg); vfs_unbusy(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Used by statfs conversion routines to scale the block size up if * necessary so that all of the block counts are <= 'max_size'. Note * that 'max_size' should be a bitmask, i.e. 2^n - 1 for some non-zero * value of 'n'. */ void statfs_scale_blocks(struct statfs *sf, long max_size) { uint64_t count; int shift; KASSERT(powerof2(max_size + 1), ("%s: invalid max_size", __func__)); /* * Attempt to scale the block counts to give a more accurate * overview to userland of the ratio of free space to used * space. To do this, find the largest block count and compute * a divisor that lets it fit into a signed integer <= max_size. */ if (sf->f_bavail < 0) count = -sf->f_bavail; else count = sf->f_bavail; count = MAX(sf->f_blocks, MAX(sf->f_bfree, count)); if (count <= max_size) return; count >>= flsl(max_size); shift = 0; while (count > 0) { shift++; count >>=1; } sf->f_bsize <<= shift; sf->f_blocks >>= shift; sf->f_bfree >>= shift; sf->f_bavail >>= shift; } /* * Get filesystem statistics. */ #ifndef _SYS_SYSPROTO_H_ struct statfs_args { char *path; struct statfs *buf; }; #endif int sys_statfs(td, uap) struct thread *td; register struct statfs_args /* { char *path; struct statfs *buf; } */ *uap; { struct statfs sf; int error; error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf); if (error == 0) error = copyout(&sf, uap->buf, sizeof(sf)); return (error); } int kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, struct statfs *buf) { struct mount *mp; struct statfs *sp, sb; int vfslocked; int error; struct nameidata nd; NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, td); error = namei(&nd); if (error) return (error); vfslocked = NDHASGIANT(&nd); mp = nd.ni_vp->v_mount; vfs_ref(mp); NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_vp); error = vfs_busy(mp, 0); vfs_rel(mp); if (error) { VFS_UNLOCK_GIANT(vfslocked); return (error); } #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); if (error) goto out; #endif /* * Set these in case the underlying filesystem fails to do so. */ sp = &mp->mnt_stat; sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp); if (error) goto out; if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; prison_enforce_statfs(td->td_ucred, mp, &sb); sp = &sb; } *buf = *sp; out: vfs_unbusy(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Get filesystem statistics. */ #ifndef _SYS_SYSPROTO_H_ struct fstatfs_args { int fd; struct statfs *buf; }; #endif int sys_fstatfs(td, uap) struct thread *td; register struct fstatfs_args /* { int fd; struct statfs *buf; } */ *uap; { struct statfs sf; int error; error = kern_fstatfs(td, uap->fd, &sf); if (error == 0) error = copyout(&sf, uap->buf, sizeof(sf)); return (error); } int kern_fstatfs(struct thread *td, int fd, struct statfs *buf) { struct file *fp; struct mount *mp; struct statfs *sp, sb; int vfslocked; struct vnode *vp; int error; AUDIT_ARG_FD(fd); error = getvnode(td->td_proc->p_fd, fd, CAP_FSTATFS, &fp); if (error) return (error); vp = fp->f_vnode; vfslocked = VFS_LOCK_GIANT(vp->v_mount); vn_lock(vp, LK_SHARED | LK_RETRY); #ifdef AUDIT AUDIT_ARG_VNODE1(vp); #endif mp = vp->v_mount; if (mp) vfs_ref(mp); VOP_UNLOCK(vp, 0); fdrop(fp, td); if (mp == NULL) { error = EBADF; goto out; } error = vfs_busy(mp, 0); vfs_rel(mp); if (error) { VFS_UNLOCK_GIANT(vfslocked); return (error); } #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); if (error) goto out; #endif /* * Set these in case the underlying filesystem fails to do so. */ sp = &mp->mnt_stat; sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp); if (error) goto out; if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; prison_enforce_statfs(td->td_ucred, mp, &sb); sp = &sb; } *buf = *sp; out: if (mp) vfs_unbusy(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Get statistics on all filesystems. */ #ifndef _SYS_SYSPROTO_H_ struct getfsstat_args { struct statfs *buf; long bufsize; int flags; }; #endif int sys_getfsstat(td, uap) struct thread *td; register struct getfsstat_args /* { struct statfs *buf; long bufsize; int flags; } */ *uap; { return (kern_getfsstat(td, &uap->buf, uap->bufsize, UIO_USERSPACE, uap->flags)); } /* * If (bufsize > 0 && bufseg == UIO_SYSSPACE) * The caller is responsible for freeing memory which will be allocated * in '*buf'. */ int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, enum uio_seg bufseg, int flags) { struct mount *mp, *nmp; struct statfs *sfsp, *sp, sb; size_t count, maxcount; int vfslocked; int error; maxcount = bufsize / sizeof(struct statfs); if (bufsize == 0) sfsp = NULL; else if (bufseg == UIO_USERSPACE) sfsp = *buf; else /* if (bufseg == UIO_SYSSPACE) */ { count = 0; mtx_lock(&mountlist_mtx); TAILQ_FOREACH(mp, &mountlist, mnt_list) { count++; } mtx_unlock(&mountlist_mtx); if (maxcount > count) maxcount = count; sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_TEMP, M_WAITOK); } count = 0; mtx_lock(&mountlist_mtx); for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { if (prison_canseemount(td->td_ucred, mp) != 0) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } #ifdef MAC if (mac_mount_check_stat(td->td_ucred, mp) != 0) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } #endif if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } vfslocked = VFS_LOCK_GIANT(mp); if (sfsp && count < maxcount) { sp = &mp->mnt_stat; /* * Set these in case the underlying filesystem * fails to do so. */ sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; /* * If MNT_NOWAIT or MNT_LAZY is specified, do not * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY * overrides MNT_WAIT. */ if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || (flags & MNT_WAIT)) && (error = VFS_STATFS(mp, sp))) { VFS_UNLOCK_GIANT(vfslocked); mtx_lock(&mountlist_mtx); nmp = TAILQ_NEXT(mp, mnt_list); vfs_unbusy(mp); continue; } if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; prison_enforce_statfs(td->td_ucred, mp, &sb); sp = &sb; } if (bufseg == UIO_SYSSPACE) bcopy(sp, sfsp, sizeof(*sp)); else /* if (bufseg == UIO_USERSPACE) */ { error = copyout(sp, sfsp, sizeof(*sp)); if (error) { vfs_unbusy(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } } sfsp++; } VFS_UNLOCK_GIANT(vfslocked); count++; mtx_lock(&mountlist_mtx); nmp = TAILQ_NEXT(mp, mnt_list); vfs_unbusy(mp); } mtx_unlock(&mountlist_mtx); if (sfsp && count > maxcount) td->td_retval[0] = maxcount; else td->td_retval[0] = count; return (0); } #ifdef COMPAT_FREEBSD4 /* * Get old format filesystem statistics. */ static void cvtstatfs(struct statfs *, struct ostatfs *); #ifndef _SYS_SYSPROTO_H_ struct freebsd4_statfs_args { char *path; struct ostatfs *buf; }; #endif int freebsd4_statfs(td, uap) struct thread *td; struct freebsd4_statfs_args /* { char *path; struct ostatfs *buf; } */ *uap; { struct ostatfs osb; struct statfs sf; int error; error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf); if (error) return (error); cvtstatfs(&sf, &osb); return (copyout(&osb, uap->buf, sizeof(osb))); } /* * Get filesystem statistics. */ #ifndef _SYS_SYSPROTO_H_ struct freebsd4_fstatfs_args { int fd; struct ostatfs *buf; }; #endif int freebsd4_fstatfs(td, uap) struct thread *td; struct freebsd4_fstatfs_args /* { int fd; struct ostatfs *buf; } */ *uap; { struct ostatfs osb; struct statfs sf; int error; error = kern_fstatfs(td, uap->fd, &sf); if (error) return (error); cvtstatfs(&sf, &osb); return (copyout(&osb, uap->buf, sizeof(osb))); } /* * Get statistics on all filesystems. */ #ifndef _SYS_SYSPROTO_H_ struct freebsd4_getfsstat_args { struct ostatfs *buf; long bufsize; int flags; }; #endif int freebsd4_getfsstat(td, uap) struct thread *td; register struct freebsd4_getfsstat_args /* { struct ostatfs *buf; long bufsize; int flags; } */ *uap; { struct statfs *buf, *sp; struct ostatfs osb; size_t count, size; int error; count = uap->bufsize / sizeof(struct ostatfs); size = count * sizeof(struct statfs); error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); if (size > 0) { count = td->td_retval[0]; sp = buf; while (count > 0 && error == 0) { cvtstatfs(sp, &osb); error = copyout(&osb, uap->buf, sizeof(osb)); sp++; uap->buf++; count--; } free(buf, M_TEMP); } return (error); } /* * Implement fstatfs() for (NFS) file handles. */ #ifndef _SYS_SYSPROTO_H_ struct freebsd4_fhstatfs_args { struct fhandle *u_fhp; struct ostatfs *buf; }; #endif int freebsd4_fhstatfs(td, uap) struct thread *td; struct freebsd4_fhstatfs_args /* { struct fhandle *u_fhp; struct ostatfs *buf; } */ *uap; { struct ostatfs osb; struct statfs sf; fhandle_t fh; int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); if (error) return (error); error = kern_fhstatfs(td, fh, &sf); if (error) return (error); cvtstatfs(&sf, &osb); return (copyout(&osb, uap->buf, sizeof(osb))); } /* * Convert a new format statfs structure to an old format statfs structure. */ static void cvtstatfs(nsp, osp) struct statfs *nsp; struct ostatfs *osp; { statfs_scale_blocks(nsp, LONG_MAX); bzero(osp, sizeof(*osp)); osp->f_bsize = nsp->f_bsize; osp->f_iosize = MIN(nsp->f_iosize, LONG_MAX); osp->f_blocks = nsp->f_blocks; osp->f_bfree = nsp->f_bfree; osp->f_bavail = nsp->f_bavail; osp->f_files = MIN(nsp->f_files, LONG_MAX); osp->f_ffree = MIN(nsp->f_ffree, LONG_MAX); osp->f_owner = nsp->f_owner; osp->f_type = nsp->f_type; osp->f_flags = nsp->f_flags; osp->f_syncwrites = MIN(nsp->f_syncwrites, LONG_MAX); osp->f_asyncwrites = MIN(nsp->f_asyncwrites, LONG_MAX); osp->f_syncreads = MIN(nsp->f_syncreads, LONG_MAX); osp->f_asyncreads = MIN(nsp->f_asyncreads, LONG_MAX); strlcpy(osp->f_fstypename, nsp->f_fstypename, MIN(MFSNAMELEN, OMFSNAMELEN)); strlcpy(osp->f_mntonname, nsp->f_mntonname, MIN(MNAMELEN, OMNAMELEN)); strlcpy(osp->f_mntfromname, nsp->f_mntfromname, MIN(MNAMELEN, OMNAMELEN)); osp->f_fsid = nsp->f_fsid; } #endif /* COMPAT_FREEBSD4 */ /* * Change current working directory to a given file descriptor. */ #ifndef _SYS_SYSPROTO_H_ struct fchdir_args { int fd; }; #endif int sys_fchdir(td, uap) struct thread *td; struct fchdir_args /* { int fd; } */ *uap; { register struct filedesc *fdp = td->td_proc->p_fd; struct vnode *vp, *tdp, *vpold; struct mount *mp; struct file *fp; int vfslocked; int error; AUDIT_ARG_FD(uap->fd); if ((error = getvnode(fdp, uap->fd, CAP_FCHDIR, &fp)) != 0) return (error); vp = fp->f_vnode; VREF(vp); fdrop(fp, td); vfslocked = VFS_LOCK_GIANT(vp->v_mount); vn_lock(vp, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(vp); error = change_dir(vp, td); while (!error && (mp = vp->v_mountedhere) != NULL) { int tvfslocked; if (vfs_busy(mp, 0)) continue; tvfslocked = VFS_LOCK_GIANT(mp); error = VFS_ROOT(mp, LK_SHARED, &tdp); vfs_unbusy(mp); if (error) { VFS_UNLOCK_GIANT(tvfslocked); break; } vput(vp); VFS_UNLOCK_GIANT(vfslocked); vp = tdp; vfslocked = tvfslocked; } if (error) { vput(vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); FILEDESC_XLOCK(fdp); vpold = fdp->fd_cdir; fdp->fd_cdir = vp; FILEDESC_XUNLOCK(fdp); vfslocked = VFS_LOCK_GIANT(vpold->v_mount); vrele(vpold); VFS_UNLOCK_GIANT(vfslocked); return (0); } /* * Change current working directory (``.''). */ #ifndef _SYS_SYSPROTO_H_ struct chdir_args { char *path; }; #endif int sys_chdir(td, uap) struct thread *td; struct chdir_args /* { char *path; } */ *uap; { return (kern_chdir(td, uap->path, UIO_USERSPACE)); } int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg) { register struct filedesc *fdp = td->td_proc->p_fd; int error; struct nameidata nd; struct vnode *vp; int vfslocked; NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); if ((error = change_dir(nd.ni_vp, td)) != 0) { vput(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); NDFREE(&nd, NDF_ONLY_PNBUF); return (error); } VOP_UNLOCK(nd.ni_vp, 0); VFS_UNLOCK_GIANT(vfslocked); NDFREE(&nd, NDF_ONLY_PNBUF); FILEDESC_XLOCK(fdp); vp = fdp->fd_cdir; fdp->fd_cdir = nd.ni_vp; FILEDESC_XUNLOCK(fdp); vfslocked = VFS_LOCK_GIANT(vp->v_mount); vrele(vp); VFS_UNLOCK_GIANT(vfslocked); return (0); } /* * Helper function for raised chroot(2) security function: Refuse if * any filedescriptors are open directories. */ static int chroot_refuse_vdir_fds(fdp) struct filedesc *fdp; { struct vnode *vp; struct file *fp; int fd; FILEDESC_LOCK_ASSERT(fdp); for (fd = 0; fd < fdp->fd_nfiles ; fd++) { fp = fget_locked(fdp, fd); if (fp == NULL) continue; if (fp->f_type == DTYPE_VNODE) { vp = fp->f_vnode; if (vp->v_type == VDIR) return (EPERM); } } return (0); } /* * This sysctl determines if we will allow a process to chroot(2) if it * has a directory open: * 0: disallowed for all processes. * 1: allowed for processes that were not already chroot(2)'ed. * 2: allowed for all processes. */ static int chroot_allow_open_directories = 1; SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW, &chroot_allow_open_directories, 0, ""); /* * Change notion of root (``/'') directory. */ #ifndef _SYS_SYSPROTO_H_ struct chroot_args { char *path; }; #endif int sys_chroot(td, uap) struct thread *td; struct chroot_args /* { char *path; } */ *uap; { int error; struct nameidata nd; int vfslocked; error = priv_check(td, PRIV_VFS_CHROOT); if (error) return (error); NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1, UIO_USERSPACE, uap->path, td); error = namei(&nd); if (error) goto error; vfslocked = NDHASGIANT(&nd); if ((error = change_dir(nd.ni_vp, td)) != 0) goto e_vunlock; #ifdef MAC if ((error = mac_vnode_check_chroot(td->td_ucred, nd.ni_vp))) goto e_vunlock; #endif VOP_UNLOCK(nd.ni_vp, 0); error = change_root(nd.ni_vp, td); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); NDFREE(&nd, NDF_ONLY_PNBUF); return (error); e_vunlock: vput(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); error: NDFREE(&nd, NDF_ONLY_PNBUF); return (error); } /* * Common routine for chroot and chdir. Callers must provide a locked vnode * instance. */ int change_dir(vp, td) struct vnode *vp; struct thread *td; { int error; ASSERT_VOP_LOCKED(vp, "change_dir(): vp not locked"); if (vp->v_type != VDIR) return (ENOTDIR); #ifdef MAC error = mac_vnode_check_chdir(td->td_ucred, vp); if (error) return (error); #endif error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td); return (error); } /* * Common routine for kern_chroot() and jail_attach(). The caller is * responsible for invoking priv_check() and mac_vnode_check_chroot() to * authorize this operation. */ int change_root(vp, td) struct vnode *vp; struct thread *td; { struct filedesc *fdp; struct vnode *oldvp; int vfslocked; int error; VFS_ASSERT_GIANT(vp->v_mount); fdp = td->td_proc->p_fd; FILEDESC_XLOCK(fdp); if (chroot_allow_open_directories == 0 || (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) { error = chroot_refuse_vdir_fds(fdp); if (error) { FILEDESC_XUNLOCK(fdp); return (error); } } oldvp = fdp->fd_rdir; fdp->fd_rdir = vp; VREF(fdp->fd_rdir); if (!fdp->fd_jdir) { fdp->fd_jdir = vp; VREF(fdp->fd_jdir); } FILEDESC_XUNLOCK(fdp); vfslocked = VFS_LOCK_GIANT(oldvp->v_mount); vrele(oldvp); VFS_UNLOCK_GIANT(vfslocked); return (0); } static __inline cap_rights_t flags_to_rights(int flags) { cap_rights_t rights = 0; switch ((flags & O_ACCMODE)) { case O_RDONLY: rights |= CAP_READ; break; case O_RDWR: rights |= CAP_READ; /* fall through */ case O_WRONLY: rights |= CAP_WRITE; break; case O_EXEC: rights |= CAP_FEXECVE; break; } if (flags & O_CREAT) rights |= CAP_CREATE; if (flags & O_TRUNC) rights |= CAP_FTRUNCATE; if ((flags & O_EXLOCK) || (flags & O_SHLOCK)) rights |= CAP_FLOCK; return (rights); } /* * Check permissions, allocate an open file structure, and call the device * open routine if any. */ #ifndef _SYS_SYSPROTO_H_ struct open_args { char *path; int flags; int mode; }; #endif int sys_open(td, uap) struct thread *td; register struct open_args /* { char *path; int flags; int mode; } */ *uap; { return (kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode)); } #ifndef _SYS_SYSPROTO_H_ struct openat_args { int fd; char *path; int flag; int mode; }; #endif int sys_openat(struct thread *td, struct openat_args *uap) { return (kern_openat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, uap->mode)); } int kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, int mode) { return (kern_openat(td, AT_FDCWD, path, pathseg, flags, mode)); } int kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int flags, int mode) { struct proc *p = td->td_proc; struct filedesc *fdp = p->p_fd; struct file *fp; struct vnode *vp; int cmode; struct file *nfp; int type, indx = -1, error, error_open; struct flock lf; struct nameidata nd; int vfslocked; cap_rights_t rights_needed = CAP_LOOKUP; AUDIT_ARG_FFLAGS(flags); AUDIT_ARG_MODE(mode); /* XXX: audit dirfd */ rights_needed |= flags_to_rights(flags); /* * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags * may be specified. */ if (flags & O_EXEC) { if (flags & O_ACCMODE) return (EINVAL); } else if ((flags & O_ACCMODE) == O_ACCMODE) return (EINVAL); else flags = FFLAGS(flags); /* * allocate the file descriptor, but don't install a descriptor yet */ error = falloc_noinstall(td, &nfp); if (error) return (error); /* An extra reference on `nfp' has been held for us by falloc_noinstall(). */ fp = nfp; /* Set the flags early so the finit in devfs can pick them up. */ fp->f_flag = flags & FMASK; cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, fd, rights_needed, td); td->td_dupfd = -1; /* XXX check for fdopen */ error = vn_open(&nd, &flags, cmode, fp); if (error) { /* * If the vn_open replaced the method vector, something * wonderous happened deep below and we just pass it up * pretending we know what we do. */ if (error == ENXIO && fp->f_ops != &badfileops) goto success; /* * handle special fdopen() case. bleh. dupfdopen() is * responsible for dropping the old contents of ofiles[indx] * if it succeeds. * * Don't do this for relative (capability) lookups; we don't * understand exactly what would happen, and we don't think * that it ever should. */ if ((nd.ni_strictrelative == 0) && (error == ENODEV || error == ENXIO) && (td->td_dupfd >= 0)) { /* XXX from fdopen */ error_open = error; if ((error = finstall(td, fp, &indx, flags)) != 0) goto bad_unlocked; if ((error = dupfdopen(td, fdp, indx, td->td_dupfd, flags, error_open)) == 0) goto success; } /* * Clean up the descriptor, but only if another thread hadn't * replaced or closed it. */ if (indx != -1) fdclose(fdp, fp, indx, td); fdrop(fp, td); if (error == ERESTART) error = EINTR; return (error); } td->td_dupfd = 0; vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; /* * Store the vnode, for any f_type. Typically, the vnode use * count is decremented by direct call to vn_closefile() for * files that switched type in the cdevsw fdopen() method. */ fp->f_vnode = vp; /* * If the file wasn't claimed by devfs bind it to the normal * vnode operations here. */ if (fp->f_ops == &badfileops) { KASSERT(vp->v_type != VFIFO, ("Unexpected fifo.")); fp->f_seqcount = 1; finit(fp, flags & FMASK, DTYPE_VNODE, vp, &vnops); } VOP_UNLOCK(vp, 0); if (fp->f_type == DTYPE_VNODE && (flags & (O_EXLOCK | O_SHLOCK)) != 0) { lf.l_whence = SEEK_SET; lf.l_start = 0; lf.l_len = 0; if (flags & O_EXLOCK) lf.l_type = F_WRLCK; else lf.l_type = F_RDLCK; type = F_FLOCK; if ((flags & FNONBLOCK) == 0) type |= F_WAIT; if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) goto bad; atomic_set_int(&fp->f_flag, FHASLOCK); } if (flags & O_TRUNC) { error = fo_truncate(fp, 0, td->td_ucred, td); if (error) goto bad; } VFS_UNLOCK_GIANT(vfslocked); success: /* * If we haven't already installed the FD (for dupfdopen), do so now. */ if (indx == -1) { #ifdef CAPABILITIES if (nd.ni_strictrelative == 1) { /* * We are doing a strict relative lookup; wrap the * result in a capability. */ if ((error = kern_capwrap(td, fp, nd.ni_baserights, &indx)) != 0) goto bad_unlocked; } else #endif if ((error = finstall(td, fp, &indx, flags)) != 0) goto bad_unlocked; } /* * Release our private reference, leaving the one associated with * the descriptor table intact. */ fdrop(fp, td); td->td_retval[0] = indx; return (0); bad: VFS_UNLOCK_GIANT(vfslocked); bad_unlocked: if (indx != -1) fdclose(fdp, fp, indx, td); fdrop(fp, td); td->td_retval[0] = -1; return (error); } #ifdef COMPAT_43 /* * Create a file. */ #ifndef _SYS_SYSPROTO_H_ struct ocreat_args { char *path; int mode; }; #endif int ocreat(td, uap) struct thread *td; register struct ocreat_args /* { char *path; int mode; } */ *uap; { return (kern_open(td, uap->path, UIO_USERSPACE, O_WRONLY | O_CREAT | O_TRUNC, uap->mode)); } #endif /* COMPAT_43 */ /* * Create a special file. */ #ifndef _SYS_SYSPROTO_H_ struct mknod_args { char *path; int mode; int dev; }; #endif int sys_mknod(td, uap) struct thread *td; register struct mknod_args /* { char *path; int mode; int dev; } */ *uap; { return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); } #ifndef _SYS_SYSPROTO_H_ struct mknodat_args { int fd; char *path; mode_t mode; dev_t dev; }; #endif int sys_mknodat(struct thread *td, struct mknodat_args *uap) { return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); } int kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode, int dev) { return (kern_mknodat(td, AT_FDCWD, path, pathseg, mode, dev)); } int kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int mode, int dev) { struct vnode *vp; struct mount *mp; struct vattr vattr; int error; int whiteout = 0; struct nameidata nd; int vfslocked; AUDIT_ARG_MODE(mode); AUDIT_ARG_DEV(dev); switch (mode & S_IFMT) { case S_IFCHR: case S_IFBLK: error = priv_check(td, PRIV_VFS_MKNOD_DEV); break; case S_IFMT: error = priv_check(td, PRIV_VFS_MKNOD_BAD); break; case S_IFWHT: error = priv_check(td, PRIV_VFS_MKNOD_WHT); break; case S_IFIFO: if (dev == 0) return (kern_mkfifoat(td, fd, path, pathseg, mode)); /* FALLTHROUGH */ default: error = EINVAL; break; } if (error) return (error); restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, pathseg, path, fd, CAP_MKFIFO, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; if (vp != NULL) { NDFREE(&nd, NDF_ONLY_PNBUF); if (vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(vp); VFS_UNLOCK_GIANT(vfslocked); return (EEXIST); } else { VATTR_NULL(&vattr); vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; vattr.va_rdev = dev; whiteout = 0; switch (mode & S_IFMT) { case S_IFMT: /* used by badsect to flag bad sectors */ vattr.va_type = VBAD; break; case S_IFCHR: vattr.va_type = VCHR; break; case S_IFBLK: vattr.va_type = VBLK; break; case S_IFWHT: whiteout = 1; break; default: panic("kern_mknod: invalid mode"); } } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } #ifdef MAC if (error == 0 && !whiteout) error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); #endif if (!error) { if (whiteout) error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); else { error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); if (error == 0) vput(nd.ni_vp); } } NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Create a named pipe. */ #ifndef _SYS_SYSPROTO_H_ struct mkfifo_args { char *path; int mode; }; #endif int sys_mkfifo(td, uap) struct thread *td; register struct mkfifo_args /* { char *path; int mode; } */ *uap; { return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode)); } #ifndef _SYS_SYSPROTO_H_ struct mkfifoat_args { int fd; char *path; mode_t mode; }; #endif int sys_mkfifoat(struct thread *td, struct mkfifoat_args *uap) { return (kern_mkfifoat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); } int kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode) { return (kern_mkfifoat(td, AT_FDCWD, path, pathseg, mode)); } int kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int mode) { struct mount *mp; struct vattr vattr; int error; struct nameidata nd; int vfslocked; AUDIT_ARG_MODE(mode); restart: bwillwrite(); NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, pathseg, path, fd, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); if (nd.ni_vp != NULL) { NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (EEXIST); } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } VATTR_NULL(&vattr); vattr.va_type = VFIFO; vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; #ifdef MAC error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); if (error) goto out; #endif error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); if (error == 0) vput(nd.ni_vp); #ifdef MAC out: #endif vput(nd.ni_dvp); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); NDFREE(&nd, NDF_ONLY_PNBUF); return (error); } /* * Make a hard file link. */ #ifndef _SYS_SYSPROTO_H_ struct link_args { char *path; char *link; }; #endif int sys_link(td, uap) struct thread *td; register struct link_args /* { char *path; char *link; } */ *uap; { return (kern_link(td, uap->path, uap->link, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ struct linkat_args { int fd1; char *path1; int fd2; char *path2; int flag; }; #endif int sys_linkat(struct thread *td, struct linkat_args *uap) { int flag; flag = uap->flag; if (flag & ~AT_SYMLINK_FOLLOW) return (EINVAL); return (kern_linkat(td, uap->fd1, uap->fd2, uap->path1, uap->path2, UIO_USERSPACE, (flag & AT_SYMLINK_FOLLOW) ? FOLLOW : NOFOLLOW)); } int hardlink_check_uid = 0; SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW, &hardlink_check_uid, 0, "Unprivileged processes cannot create hard links to files owned by other " "users"); static int hardlink_check_gid = 0; SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW, &hardlink_check_gid, 0, "Unprivileged processes cannot create hard links to files owned by other " "groups"); static int can_hardlink(struct vnode *vp, struct ucred *cred) { struct vattr va; int error; if (!hardlink_check_uid && !hardlink_check_gid) return (0); error = VOP_GETATTR(vp, &va, cred); if (error != 0) return (error); if (hardlink_check_uid && cred->cr_uid != va.va_uid) { error = priv_check_cred(cred, PRIV_VFS_LINK, 0); if (error) return (error); } if (hardlink_check_gid && !groupmember(va.va_gid, cred)) { error = priv_check_cred(cred, PRIV_VFS_LINK, 0); if (error) return (error); } return (0); } int kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg) { return (kern_linkat(td, AT_FDCWD, AT_FDCWD, path,link, segflg, FOLLOW)); } int kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, enum uio_seg segflg, int follow) { struct vnode *vp; struct mount *mp; struct nameidata nd; int vfslocked; int lvfslocked; int error; bwillwrite(); NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, segflg, path1, fd1, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; if (vp->v_type == VDIR) { vrele(vp); VFS_UNLOCK_GIANT(vfslocked); return (EPERM); /* POSIX */ } if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { vrele(vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE2, segflg, path2, fd2, td); if ((error = namei(&nd)) == 0) { lvfslocked = NDHASGIANT(&nd); if (nd.ni_vp != NULL) { if (nd.ni_dvp == nd.ni_vp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(nd.ni_vp); error = EEXIST; } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) == 0) { error = can_hardlink(vp, td->td_ucred); if (error == 0) #ifdef MAC error = mac_vnode_check_link(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); if (error == 0) #endif error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); VOP_UNLOCK(vp, 0); vput(nd.ni_dvp); } NDFREE(&nd, NDF_ONLY_PNBUF); VFS_UNLOCK_GIANT(lvfslocked); } vrele(vp); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Make a symbolic link. */ #ifndef _SYS_SYSPROTO_H_ struct symlink_args { char *path; char *link; }; #endif int sys_symlink(td, uap) struct thread *td; register struct symlink_args /* { char *path; char *link; } */ *uap; { return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ struct symlinkat_args { char *path; int fd; char *path2; }; #endif int sys_symlinkat(struct thread *td, struct symlinkat_args *uap) { return (kern_symlinkat(td, uap->path1, uap->fd, uap->path2, UIO_USERSPACE)); } int kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg) { return (kern_symlinkat(td, path, AT_FDCWD, link, segflg)); } int kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, enum uio_seg segflg) { struct mount *mp; struct vattr vattr; char *syspath; int error; struct nameidata nd; int vfslocked; if (segflg == UIO_SYSSPACE) { syspath = path1; } else { syspath = uma_zalloc(namei_zone, M_WAITOK); if ((error = copyinstr(path1, syspath, MAXPATHLEN, NULL)) != 0) goto out; } AUDIT_ARG_TEXT(syspath); restart: bwillwrite(); NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, segflg, path2, fd, td); if ((error = namei(&nd)) != 0) goto out; vfslocked = NDHASGIANT(&nd); if (nd.ni_vp) { NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); error = EEXIST; goto out; } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) goto out; goto restart; } VATTR_NULL(&vattr); vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask; #ifdef MAC vattr.va_type = VLNK; error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); if (error) goto out2; #endif error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); if (error == 0) vput(nd.ni_vp); #ifdef MAC out2: #endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); out: if (segflg != UIO_SYSSPACE) uma_zfree(namei_zone, syspath); return (error); } /* * Delete a whiteout from the filesystem. */ int sys_undelete(td, uap) struct thread *td; register struct undelete_args /* { char *path; } */ *uap; { int error; struct mount *mp; struct nameidata nd; int vfslocked; restart: bwillwrite(); NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | MPSAFE | AUDITVNODE1, UIO_USERSPACE, uap->path, td); error = namei(&nd); if (error) return (error); vfslocked = NDHASGIANT(&nd); if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); if (nd.ni_vp) vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (EEXIST); } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE); NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Delete a name from the filesystem. */ #ifndef _SYS_SYSPROTO_H_ struct unlink_args { char *path; }; #endif int sys_unlink(td, uap) struct thread *td; struct unlink_args /* { char *path; } */ *uap; { return (kern_unlink(td, uap->path, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ struct unlinkat_args { int fd; char *path; int flag; }; #endif int sys_unlinkat(struct thread *td, struct unlinkat_args *uap) { int flag = uap->flag; int fd = uap->fd; char *path = uap->path; if (flag & ~AT_REMOVEDIR) return (EINVAL); if (flag & AT_REMOVEDIR) return (kern_rmdirat(td, fd, path, UIO_USERSPACE)); else return (kern_unlinkat(td, fd, path, UIO_USERSPACE, 0)); } int kern_unlink(struct thread *td, char *path, enum uio_seg pathseg) { return (kern_unlinkat(td, AT_FDCWD, path, pathseg, 0)); } int kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, ino_t oldinum) { struct mount *mp; struct vnode *vp; int error; struct nameidata nd; struct stat sb; int vfslocked; restart: bwillwrite(); NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, fd, td); if ((error = namei(&nd)) != 0) return (error == EINVAL ? EPERM : error); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; if (vp->v_type == VDIR && oldinum == 0) { error = EPERM; /* POSIX */ } else if (oldinum != 0 && ((error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td)) == 0) && sb.st_ino != oldinum) { error = EIDRM; /* Identifier removed */ } else { /* * The root of a mounted filesystem cannot be deleted. * * XXX: can this only be a VDIR case? */ if (vp->v_vflag & VV_ROOT) error = EBUSY; } if (error == 0) { if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if (vp == nd.ni_dvp) vrele(vp); else vput(vp); VFS_UNLOCK_GIANT(vfslocked); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } #ifdef MAC error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); if (error) goto out; #endif error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); #ifdef MAC out: #endif vn_finished_write(mp); } NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if (vp == nd.ni_dvp) vrele(vp); else vput(vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Reposition read/write file offset. */ #ifndef _SYS_SYSPROTO_H_ struct lseek_args { int fd; int pad; off_t offset; int whence; }; #endif int sys_lseek(td, uap) struct thread *td; register struct lseek_args /* { int fd; int pad; off_t offset; int whence; } */ *uap; { struct ucred *cred = td->td_ucred; struct file *fp; struct vnode *vp; struct vattr vattr; off_t offset, size; int error, noneg; int vfslocked; AUDIT_ARG_FD(uap->fd); if ((error = fget(td, uap->fd, CAP_SEEK, &fp)) != 0) return (error); if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) { fdrop(fp, td); return (ESPIPE); } vp = fp->f_vnode; vfslocked = VFS_LOCK_GIANT(vp->v_mount); noneg = (vp->v_type != VCHR); offset = uap->offset; switch (uap->whence) { case L_INCR: if (noneg && (fp->f_offset < 0 || (offset > 0 && fp->f_offset > OFF_MAX - offset))) { error = EOVERFLOW; break; } offset += fp->f_offset; break; case L_XTND: vn_lock(vp, LK_SHARED | LK_RETRY); error = VOP_GETATTR(vp, &vattr, cred); VOP_UNLOCK(vp, 0); if (error) break; /* * If the file references a disk device, then fetch * the media size and use that to determine the ending * offset. */ if (vattr.va_size == 0 && vp->v_type == VCHR && fo_ioctl(fp, DIOCGMEDIASIZE, &size, cred, td) == 0) vattr.va_size = size; if (noneg && (vattr.va_size > OFF_MAX || (offset > 0 && vattr.va_size > OFF_MAX - offset))) { error = EOVERFLOW; break; } offset += vattr.va_size; break; case L_SET: break; case SEEK_DATA: error = fo_ioctl(fp, FIOSEEKDATA, &offset, cred, td); break; case SEEK_HOLE: error = fo_ioctl(fp, FIOSEEKHOLE, &offset, cred, td); break; default: error = EINVAL; } if (error == 0 && noneg && offset < 0) error = EINVAL; if (error != 0) goto drop; fp->f_offset = offset; *(off_t *)(td->td_retval) = fp->f_offset; drop: fdrop(fp, td); VFS_UNLOCK_GIANT(vfslocked); return (error); } #if defined(COMPAT_43) /* * Reposition read/write file offset. */ #ifndef _SYS_SYSPROTO_H_ struct olseek_args { int fd; long offset; int whence; }; #endif int olseek(td, uap) struct thread *td; register struct olseek_args /* { int fd; long offset; int whence; } */ *uap; { struct lseek_args /* { int fd; int pad; off_t offset; int whence; } */ nuap; nuap.fd = uap->fd; nuap.offset = uap->offset; nuap.whence = uap->whence; return (sys_lseek(td, &nuap)); } #endif /* COMPAT_43 */ /* Version with the 'pad' argument */ int freebsd6_lseek(td, uap) struct thread *td; register struct freebsd6_lseek_args *uap; { struct lseek_args ouap; ouap.fd = uap->fd; ouap.offset = uap->offset; ouap.whence = uap->whence; return (sys_lseek(td, &ouap)); } /* * Check access permissions using passed credentials. */ static int vn_access(vp, user_flags, cred, td) struct vnode *vp; int user_flags; struct ucred *cred; struct thread *td; { int error; accmode_t accmode; /* Flags == 0 means only check for existence. */ error = 0; if (user_flags) { accmode = 0; if (user_flags & R_OK) accmode |= VREAD; if (user_flags & W_OK) accmode |= VWRITE; if (user_flags & X_OK) accmode |= VEXEC; #ifdef MAC error = mac_vnode_check_access(cred, vp, accmode); if (error) return (error); #endif if ((accmode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) error = VOP_ACCESS(vp, accmode, cred, td); } return (error); } /* * Check access permissions using "real" credentials. */ #ifndef _SYS_SYSPROTO_H_ struct access_args { char *path; - int flags; + int amode; }; #endif int sys_access(td, uap) struct thread *td; register struct access_args /* { char *path; - int flags; + int amode; } */ *uap; { - return (kern_access(td, uap->path, UIO_USERSPACE, uap->flags)); + return (kern_access(td, uap->path, UIO_USERSPACE, uap->amode)); } #ifndef _SYS_SYSPROTO_H_ struct faccessat_args { int dirfd; char *path; - int mode; + int amode; int flag; } #endif int sys_faccessat(struct thread *td, struct faccessat_args *uap) { if (uap->flag & ~AT_EACCESS) return (EINVAL); return (kern_accessat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, - uap->mode)); + uap->amode)); } int -kern_access(struct thread *td, char *path, enum uio_seg pathseg, int mode) +kern_access(struct thread *td, char *path, enum uio_seg pathseg, int amode) { - return (kern_accessat(td, AT_FDCWD, path, pathseg, 0, mode)); + return (kern_accessat(td, AT_FDCWD, path, pathseg, 0, amode)); } int kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, - int flags, int mode) + int flag, int amode) { struct ucred *cred, *tmpcred; struct vnode *vp; struct nameidata nd; int vfslocked; int error; /* * Create and modify a temporary credential instead of one that * is potentially shared. */ - if (!(flags & AT_EACCESS)) { + if (!(flag & AT_EACCESS)) { cred = td->td_ucred; tmpcred = crdup(cred); tmpcred->cr_uid = cred->cr_ruid; tmpcred->cr_groups[0] = cred->cr_rgid; td->td_ucred = tmpcred; } else cred = tmpcred = td->td_ucred; - AUDIT_ARG_VALUE(mode); + AUDIT_ARG_VALUE(amode); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, fd, CAP_FSTAT, td); if ((error = namei(&nd)) != 0) goto out1; vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; - error = vn_access(vp, mode, tmpcred, td); + error = vn_access(vp, amode, tmpcred, td); NDFREE(&nd, NDF_ONLY_PNBUF); vput(vp); VFS_UNLOCK_GIANT(vfslocked); out1: - if (!(flags & AT_EACCESS)) { + if (!(flag & AT_EACCESS)) { td->td_ucred = cred; crfree(tmpcred); } return (error); } /* * Check access permissions using "effective" credentials. */ #ifndef _SYS_SYSPROTO_H_ struct eaccess_args { char *path; - int flags; + int amode; }; #endif int sys_eaccess(td, uap) struct thread *td; register struct eaccess_args /* { char *path; - int flags; + int amode; } */ *uap; { - return (kern_eaccess(td, uap->path, UIO_USERSPACE, uap->flags)); + return (kern_eaccess(td, uap->path, UIO_USERSPACE, uap->amode)); } int -kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, int flags) +kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, int amode) { - return (kern_accessat(td, AT_FDCWD, path, pathseg, AT_EACCESS, flags)); + return (kern_accessat(td, AT_FDCWD, path, pathseg, AT_EACCESS, amode)); } #if defined(COMPAT_43) /* * Get file status; this version follows links. */ #ifndef _SYS_SYSPROTO_H_ struct ostat_args { char *path; struct ostat *ub; }; #endif int ostat(td, uap) struct thread *td; register struct ostat_args /* { char *path; struct ostat *ub; } */ *uap; { struct stat sb; struct ostat osb; int error; error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); if (error) return (error); cvtstat(&sb, &osb); error = copyout(&osb, uap->ub, sizeof (osb)); return (error); } /* * Get file status; this version does not follow links. */ #ifndef _SYS_SYSPROTO_H_ struct olstat_args { char *path; struct ostat *ub; }; #endif int olstat(td, uap) struct thread *td; register struct olstat_args /* { char *path; struct ostat *ub; } */ *uap; { struct stat sb; struct ostat osb; int error; error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); if (error) return (error); cvtstat(&sb, &osb); error = copyout(&osb, uap->ub, sizeof (osb)); return (error); } /* * Convert from an old to a new stat structure. */ void cvtstat(st, ost) struct stat *st; struct ostat *ost; { ost->st_dev = st->st_dev; ost->st_ino = st->st_ino; ost->st_mode = st->st_mode; ost->st_nlink = st->st_nlink; ost->st_uid = st->st_uid; ost->st_gid = st->st_gid; ost->st_rdev = st->st_rdev; if (st->st_size < (quad_t)1 << 32) ost->st_size = st->st_size; else ost->st_size = -2; ost->st_atim = st->st_atim; ost->st_mtim = st->st_mtim; ost->st_ctim = st->st_ctim; ost->st_blksize = st->st_blksize; ost->st_blocks = st->st_blocks; ost->st_flags = st->st_flags; ost->st_gen = st->st_gen; } #endif /* COMPAT_43 */ /* * Get file status; this version follows links. */ #ifndef _SYS_SYSPROTO_H_ struct stat_args { char *path; struct stat *ub; }; #endif int sys_stat(td, uap) struct thread *td; register struct stat_args /* { char *path; struct stat *ub; } */ *uap; { struct stat sb; int error; error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); if (error == 0) error = copyout(&sb, uap->ub, sizeof (sb)); return (error); } #ifndef _SYS_SYSPROTO_H_ struct fstatat_args { int fd; char *path; struct stat *buf; int flag; } #endif int sys_fstatat(struct thread *td, struct fstatat_args *uap) { struct stat sb; int error; error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, &sb); if (error == 0) error = copyout(&sb, uap->buf, sizeof (sb)); return (error); } int kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) { return (kern_statat(td, 0, AT_FDCWD, path, pathseg, sbp)); } int kern_statat(struct thread *td, int flag, int fd, char *path, enum uio_seg pathseg, struct stat *sbp) { return (kern_statat_vnhook(td, flag, fd, path, pathseg, sbp, NULL)); } int kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, enum uio_seg pathseg, struct stat *sbp, void (*hook)(struct vnode *vp, struct stat *sbp)) { struct nameidata nd; struct stat sb; int error, vfslocked; if (flag & ~AT_SYMLINK_NOFOLLOW) return (EINVAL); NDINIT_ATRIGHTS(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg, path, fd, CAP_FSTAT, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); if (!error) { SDT_PROBE(vfs, , stat, mode, path, sb.st_mode, 0, 0, 0); if (S_ISREG(sb.st_mode)) SDT_PROBE(vfs, , stat, reg, path, pathseg, 0, 0, 0); if (__predict_false(hook != NULL)) hook(nd.ni_vp, &sb); } NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); if (error) return (error); *sbp = sb; #ifdef KTRACE if (KTRPOINT(td, KTR_STRUCT)) ktrstat(&sb); #endif return (0); } /* * Get file status; this version does not follow links. */ #ifndef _SYS_SYSPROTO_H_ struct lstat_args { char *path; struct stat *ub; }; #endif int sys_lstat(td, uap) struct thread *td; register struct lstat_args /* { char *path; struct stat *ub; } */ *uap; { struct stat sb; int error; error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); if (error == 0) error = copyout(&sb, uap->ub, sizeof (sb)); return (error); } int kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) { return (kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, pathseg, sbp)); } /* * Implementation of the NetBSD [l]stat() functions. */ void cvtnstat(sb, nsb) struct stat *sb; struct nstat *nsb; { bzero(nsb, sizeof *nsb); nsb->st_dev = sb->st_dev; nsb->st_ino = sb->st_ino; nsb->st_mode = sb->st_mode; nsb->st_nlink = sb->st_nlink; nsb->st_uid = sb->st_uid; nsb->st_gid = sb->st_gid; nsb->st_rdev = sb->st_rdev; nsb->st_atim = sb->st_atim; nsb->st_mtim = sb->st_mtim; nsb->st_ctim = sb->st_ctim; nsb->st_size = sb->st_size; nsb->st_blocks = sb->st_blocks; nsb->st_blksize = sb->st_blksize; nsb->st_flags = sb->st_flags; nsb->st_gen = sb->st_gen; nsb->st_birthtim = sb->st_birthtim; } #ifndef _SYS_SYSPROTO_H_ struct nstat_args { char *path; struct nstat *ub; }; #endif int sys_nstat(td, uap) struct thread *td; register struct nstat_args /* { char *path; struct nstat *ub; } */ *uap; { struct stat sb; struct nstat nsb; int error; error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); if (error) return (error); cvtnstat(&sb, &nsb); error = copyout(&nsb, uap->ub, sizeof (nsb)); return (error); } /* * NetBSD lstat. Get file status; this version does not follow links. */ #ifndef _SYS_SYSPROTO_H_ struct lstat_args { char *path; struct stat *ub; }; #endif int sys_nlstat(td, uap) struct thread *td; register struct nlstat_args /* { char *path; struct nstat *ub; } */ *uap; { struct stat sb; struct nstat nsb; int error; error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); if (error) return (error); cvtnstat(&sb, &nsb); error = copyout(&nsb, uap->ub, sizeof (nsb)); return (error); } /* * Get configurable pathname variables. */ #ifndef _SYS_SYSPROTO_H_ struct pathconf_args { char *path; int name; }; #endif int sys_pathconf(td, uap) struct thread *td; register struct pathconf_args /* { char *path; int name; } */ *uap; { return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name, FOLLOW)); } #ifndef _SYS_SYSPROTO_H_ struct lpathconf_args { char *path; int name; }; #endif int sys_lpathconf(td, uap) struct thread *td; register struct lpathconf_args /* { char *path; int name; } */ *uap; { return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name, NOFOLLOW)); } int kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name, u_long flags) { struct nameidata nd; int error, vfslocked; NDINIT(&nd, LOOKUP, LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1 | flags, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); /* If asynchronous I/O is available, it works for all files. */ if (name == _PC_ASYNC_IO) td->td_retval[0] = async_io_version; else error = VOP_PATHCONF(nd.ni_vp, name, td->td_retval); vput(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Return target name of a symbolic link. */ #ifndef _SYS_SYSPROTO_H_ struct readlink_args { char *path; char *buf; size_t count; }; #endif int sys_readlink(td, uap) struct thread *td; register struct readlink_args /* { char *path; char *buf; size_t count; } */ *uap; { return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf, UIO_USERSPACE, uap->count)); } #ifndef _SYS_SYSPROTO_H_ struct readlinkat_args { int fd; char *path; char *buf; size_t bufsize; }; #endif int sys_readlinkat(struct thread *td, struct readlinkat_args *uap) { return (kern_readlinkat(td, uap->fd, uap->path, UIO_USERSPACE, uap->buf, UIO_USERSPACE, uap->bufsize)); } int kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, size_t count) { return (kern_readlinkat(td, AT_FDCWD, path, pathseg, buf, bufseg, count)); } int kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, size_t count) { struct vnode *vp; struct iovec aiov; struct uio auio; int error; struct nameidata nd; int vfslocked; if (count > INT_MAX) return (EINVAL); NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, fd, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; #ifdef MAC error = mac_vnode_check_readlink(td->td_ucred, vp); if (error) { vput(vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } #endif if (vp->v_type != VLNK) error = EINVAL; else { aiov.iov_base = buf; aiov.iov_len = count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_offset = 0; auio.uio_rw = UIO_READ; auio.uio_segflg = bufseg; auio.uio_td = td; auio.uio_resid = count; error = VOP_READLINK(vp, &auio, td->td_ucred); } vput(vp); VFS_UNLOCK_GIANT(vfslocked); td->td_retval[0] = count - auio.uio_resid; return (error); } /* * Common implementation code for chflags() and fchflags(). */ static int setfflags(td, vp, flags) struct thread *td; struct vnode *vp; int flags; { int error; struct mount *mp; struct vattr vattr; /* * Prevent non-root users from setting flags on devices. When * a device is reused, users can retain ownership of the device * if they are allowed to set flags and programs assume that * chown can't fail when done as root. */ if (vp->v_type == VCHR || vp->v_type == VBLK) { error = priv_check(td, PRIV_VFS_CHFLAGS_DEV); if (error) return (error); } if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); VATTR_NULL(&vattr); vattr.va_flags = flags; #ifdef MAC error = mac_vnode_check_setflags(td->td_ucred, vp, vattr.va_flags); if (error == 0) #endif error = VOP_SETATTR(vp, &vattr, td->td_ucred); VOP_UNLOCK(vp, 0); vn_finished_write(mp); return (error); } /* * Change flags of a file given a path name. */ #ifndef _SYS_SYSPROTO_H_ struct chflags_args { char *path; int flags; }; #endif int sys_chflags(td, uap) struct thread *td; register struct chflags_args /* { char *path; int flags; } */ *uap; { int error; struct nameidata nd; int vfslocked; AUDIT_ARG_FFLAGS(uap->flags); NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, uap->path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); vfslocked = NDHASGIANT(&nd); error = setfflags(td, nd.ni_vp, uap->flags); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Same as chflags() but doesn't follow symlinks. */ int sys_lchflags(td, uap) struct thread *td; register struct lchflags_args /* { char *path; int flags; } */ *uap; { int error; struct nameidata nd; int vfslocked; AUDIT_ARG_FFLAGS(uap->flags); NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE, uap->path, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); error = setfflags(td, nd.ni_vp, uap->flags); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Change flags of a file given a file descriptor. */ #ifndef _SYS_SYSPROTO_H_ struct fchflags_args { int fd; int flags; }; #endif int sys_fchflags(td, uap) struct thread *td; register struct fchflags_args /* { int fd; int flags; } */ *uap; { struct file *fp; int vfslocked; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_FFLAGS(uap->flags); if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FCHFLAGS, &fp)) != 0) return (error); vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); #ifdef AUDIT vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(fp->f_vnode); VOP_UNLOCK(fp->f_vnode, 0); #endif error = setfflags(td, fp->f_vnode, uap->flags); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (error); } /* * Common implementation code for chmod(), lchmod() and fchmod(). */ int setfmode(td, cred, vp, mode) struct thread *td; struct ucred *cred; struct vnode *vp; int mode; { int error; struct mount *mp; struct vattr vattr; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); VATTR_NULL(&vattr); vattr.va_mode = mode & ALLPERMS; #ifdef MAC error = mac_vnode_check_setmode(cred, vp, vattr.va_mode); if (error == 0) #endif error = VOP_SETATTR(vp, &vattr, cred); VOP_UNLOCK(vp, 0); vn_finished_write(mp); return (error); } /* * Change mode of a file given path name. */ #ifndef _SYS_SYSPROTO_H_ struct chmod_args { char *path; int mode; }; #endif int sys_chmod(td, uap) struct thread *td; register struct chmod_args /* { char *path; int mode; } */ *uap; { return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode)); } #ifndef _SYS_SYSPROTO_H_ struct fchmodat_args { int dirfd; char *path; mode_t mode; int flag; } #endif int sys_fchmodat(struct thread *td, struct fchmodat_args *uap) { int flag = uap->flag; int fd = uap->fd; char *path = uap->path; mode_t mode = uap->mode; if (flag & ~AT_SYMLINK_NOFOLLOW) return (EINVAL); return (kern_fchmodat(td, fd, path, UIO_USERSPACE, mode, flag)); } int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode) { return (kern_fchmodat(td, AT_FDCWD, path, pathseg, mode, 0)); } /* * Change mode of a file given path name (don't follow links.) */ #ifndef _SYS_SYSPROTO_H_ struct lchmod_args { char *path; int mode; }; #endif int sys_lchmod(td, uap) struct thread *td; register struct lchmod_args /* { char *path; int mode; } */ *uap; { return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->mode, AT_SYMLINK_NOFOLLOW)); } int kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, mode_t mode, int flag) { int error; struct nameidata nd; int vfslocked; int follow; AUDIT_ARG_MODE(mode); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; NDINIT_ATRIGHTS(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, path, fd, CAP_FCHMOD, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); error = setfmode(td, td->td_ucred, nd.ni_vp, mode); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Change mode of a file given a file descriptor. */ #ifndef _SYS_SYSPROTO_H_ struct fchmod_args { int fd; int mode; }; #endif int sys_fchmod(struct thread *td, struct fchmod_args *uap) { struct file *fp; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_MODE(uap->mode); error = fget(td, uap->fd, CAP_FCHMOD, &fp); if (error != 0) return (error); error = fo_chmod(fp, uap->mode, td->td_ucred, td); fdrop(fp, td); return (error); } /* * Common implementation for chown(), lchown(), and fchown() */ int setfown(td, cred, vp, uid, gid) struct thread *td; struct ucred *cred; struct vnode *vp; uid_t uid; gid_t gid; { int error; struct mount *mp; struct vattr vattr; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); VATTR_NULL(&vattr); vattr.va_uid = uid; vattr.va_gid = gid; #ifdef MAC error = mac_vnode_check_setowner(cred, vp, vattr.va_uid, vattr.va_gid); if (error == 0) #endif error = VOP_SETATTR(vp, &vattr, cred); VOP_UNLOCK(vp, 0); vn_finished_write(mp); return (error); } /* * Set ownership given a path name. */ #ifndef _SYS_SYSPROTO_H_ struct chown_args { char *path; int uid; int gid; }; #endif int sys_chown(td, uap) struct thread *td; register struct chown_args /* { char *path; int uid; int gid; } */ *uap; { return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); } #ifndef _SYS_SYSPROTO_H_ struct fchownat_args { int fd; const char * path; uid_t uid; gid_t gid; int flag; }; #endif int sys_fchownat(struct thread *td, struct fchownat_args *uap) { int flag; flag = uap->flag; if (flag & ~AT_SYMLINK_NOFOLLOW) return (EINVAL); return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid, uap->gid, uap->flag)); } int kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, int gid) { return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 0)); } int kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int uid, int gid, int flag) { struct nameidata nd; int error, vfslocked, follow; AUDIT_ARG_OWNER(uid, gid); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; NDINIT_ATRIGHTS(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, path, fd, CAP_FCHOWN, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); error = setfown(td, td->td_ucred, nd.ni_vp, uid, gid); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Set ownership given a path name, do not cross symlinks. */ #ifndef _SYS_SYSPROTO_H_ struct lchown_args { char *path; int uid; int gid; }; #endif int sys_lchown(td, uap) struct thread *td; register struct lchown_args /* { char *path; int uid; int gid; } */ *uap; { return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); } int kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, int gid) { return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, AT_SYMLINK_NOFOLLOW)); } /* * Set ownership given a file descriptor. */ #ifndef _SYS_SYSPROTO_H_ struct fchown_args { int fd; int uid; int gid; }; #endif int sys_fchown(td, uap) struct thread *td; register struct fchown_args /* { int fd; int uid; int gid; } */ *uap; { struct file *fp; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_OWNER(uap->uid, uap->gid); error = fget(td, uap->fd, CAP_FCHOWN, &fp); if (error != 0) return (error); error = fo_chown(fp, uap->uid, uap->gid, td->td_ucred, td); fdrop(fp, td); return (error); } /* * Common implementation code for utimes(), lutimes(), and futimes(). */ static int getutimes(usrtvp, tvpseg, tsp) const struct timeval *usrtvp; enum uio_seg tvpseg; struct timespec *tsp; { struct timeval tv[2]; const struct timeval *tvp; int error; if (usrtvp == NULL) { vfs_timestamp(&tsp[0]); tsp[1] = tsp[0]; } else { if (tvpseg == UIO_SYSSPACE) { tvp = usrtvp; } else { if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0) return (error); tvp = tv; } if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000) return (EINVAL); TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); } return (0); } /* * Common implementation code for utimes(), lutimes(), and futimes(). */ static int setutimes(td, vp, ts, numtimes, nullflag) struct thread *td; struct vnode *vp; const struct timespec *ts; int numtimes; int nullflag; { int error, setbirthtime; struct mount *mp; struct vattr vattr; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); setbirthtime = 0; if (numtimes < 3 && !VOP_GETATTR(vp, &vattr, td->td_ucred) && timespeccmp(&ts[1], &vattr.va_birthtime, < )) setbirthtime = 1; VATTR_NULL(&vattr); vattr.va_atime = ts[0]; vattr.va_mtime = ts[1]; if (setbirthtime) vattr.va_birthtime = ts[1]; if (numtimes > 2) vattr.va_birthtime = ts[2]; if (nullflag) vattr.va_vaflags |= VA_UTIMES_NULL; #ifdef MAC error = mac_vnode_check_setutimes(td->td_ucred, vp, vattr.va_atime, vattr.va_mtime); #endif if (error == 0) error = VOP_SETATTR(vp, &vattr, td->td_ucred); VOP_UNLOCK(vp, 0); vn_finished_write(mp); return (error); } /* * Set the access and modification times of a file. */ #ifndef _SYS_SYSPROTO_H_ struct utimes_args { char *path; struct timeval *tptr; }; #endif int sys_utimes(td, uap) struct thread *td; register struct utimes_args /* { char *path; struct timeval *tptr; } */ *uap; { return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ struct futimesat_args { int fd; const char * path; const struct timeval * times; }; #endif int sys_futimesat(struct thread *td, struct futimesat_args *uap) { return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE, uap->times, UIO_USERSPACE)); } int kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) { return (kern_utimesat(td, AT_FDCWD, path, pathseg, tptr, tptrseg)); } int kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) { struct nameidata nd; struct timespec ts[2]; int error, vfslocked; if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, fd, CAP_FUTIMES, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Set the access and modification times of a file. */ #ifndef _SYS_SYSPROTO_H_ struct lutimes_args { char *path; struct timeval *tptr; }; #endif int sys_lutimes(td, uap) struct thread *td; register struct lutimes_args /* { char *path; struct timeval *tptr; } */ *uap; { return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr, UIO_USERSPACE)); } int kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) { struct timespec ts[2]; int error; struct nameidata nd; int vfslocked; if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Set the access and modification times of a file. */ #ifndef _SYS_SYSPROTO_H_ struct futimes_args { int fd; struct timeval *tptr; }; #endif int sys_futimes(td, uap) struct thread *td; register struct futimes_args /* { int fd; struct timeval *tptr; } */ *uap; { return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE)); } int kern_futimes(struct thread *td, int fd, struct timeval *tptr, enum uio_seg tptrseg) { struct timespec ts[2]; struct file *fp; int vfslocked; int error; AUDIT_ARG_FD(fd); if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); if ((error = getvnode(td->td_proc->p_fd, fd, CAP_FUTIMES, &fp)) != 0) return (error); vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount); #ifdef AUDIT vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(fp->f_vnode); VOP_UNLOCK(fp->f_vnode, 0); #endif error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (error); } /* * Truncate a file given its path name. */ #ifndef _SYS_SYSPROTO_H_ struct truncate_args { char *path; int pad; off_t length; }; #endif int sys_truncate(td, uap) struct thread *td; register struct truncate_args /* { char *path; int pad; off_t length; } */ *uap; { return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length)); } int kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length) { struct mount *mp; struct vnode *vp; struct vattr vattr; int error; struct nameidata nd; int vfslocked; if (length < 0) return(EINVAL); NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { vrele(vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } NDFREE(&nd, NDF_ONLY_PNBUF); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); if (vp->v_type == VDIR) error = EISDIR; #ifdef MAC else if ((error = mac_vnode_check_write(td->td_ucred, NOCRED, vp))) { } #endif else if ((error = vn_writechk(vp)) == 0 && (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) { VATTR_NULL(&vattr); vattr.va_size = length; error = VOP_SETATTR(vp, &vattr, td->td_ucred); } vput(vp); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } #if defined(COMPAT_43) /* * Truncate a file given its path name. */ #ifndef _SYS_SYSPROTO_H_ struct otruncate_args { char *path; long length; }; #endif int otruncate(td, uap) struct thread *td; register struct otruncate_args /* { char *path; long length; } */ *uap; { struct truncate_args /* { char *path; int pad; off_t length; } */ nuap; nuap.path = uap->path; nuap.length = uap->length; return (sys_truncate(td, &nuap)); } #endif /* COMPAT_43 */ /* Versions with the pad argument */ int freebsd6_truncate(struct thread *td, struct freebsd6_truncate_args *uap) { struct truncate_args ouap; ouap.path = uap->path; ouap.length = uap->length; return (sys_truncate(td, &ouap)); } int freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap) { struct ftruncate_args ouap; ouap.fd = uap->fd; ouap.length = uap->length; return (sys_ftruncate(td, &ouap)); } /* * Sync an open file. */ #ifndef _SYS_SYSPROTO_H_ struct fsync_args { int fd; }; #endif int sys_fsync(td, uap) struct thread *td; struct fsync_args /* { int fd; } */ *uap; { struct vnode *vp; struct mount *mp; struct file *fp; int vfslocked; int error, lock_flags; AUDIT_ARG_FD(uap->fd); if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FSYNC, &fp)) != 0) return (error); vp = fp->f_vnode; vfslocked = VFS_LOCK_GIANT(vp->v_mount); if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) goto drop; if (MNT_SHARED_WRITES(mp) || ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) { lock_flags = LK_SHARED; } else { lock_flags = LK_EXCLUSIVE; } vn_lock(vp, lock_flags | LK_RETRY); AUDIT_ARG_VNODE1(vp); if (vp->v_object != NULL) { VM_OBJECT_LOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, 0); VM_OBJECT_UNLOCK(vp->v_object); } error = VOP_FSYNC(vp, MNT_WAIT, td); VOP_UNLOCK(vp, 0); vn_finished_write(mp); drop: VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (error); } /* * Rename files. Source and destination must either both be directories, or * both not be directories. If target is a directory, it must be empty. */ #ifndef _SYS_SYSPROTO_H_ struct rename_args { char *from; char *to; }; #endif int sys_rename(td, uap) struct thread *td; register struct rename_args /* { char *from; char *to; } */ *uap; { return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ struct renameat_args { int oldfd; char *old; int newfd; char *new; }; #endif int sys_renameat(struct thread *td, struct renameat_args *uap) { return (kern_renameat(td, uap->oldfd, uap->old, uap->newfd, uap->new, UIO_USERSPACE)); } int kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) { return (kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, pathseg)); } int kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, enum uio_seg pathseg) { struct mount *mp = NULL; struct vnode *tvp, *fvp, *tdvp; struct nameidata fromnd, tond; int tvfslocked; int fvfslocked; int error; bwillwrite(); #ifdef MAC NDINIT_ATRIGHTS(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE | AUDITVNODE1, pathseg, old, oldfd, CAP_DELETE, td); #else NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE | AUDITVNODE1, pathseg, old, oldfd, CAP_DELETE, td); #endif if ((error = namei(&fromnd)) != 0) return (error); fvfslocked = NDHASGIANT(&fromnd); tvfslocked = 0; #ifdef MAC error = mac_vnode_check_rename_from(td->td_ucred, fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd); VOP_UNLOCK(fromnd.ni_dvp, 0); if (fromnd.ni_dvp != fromnd.ni_vp) VOP_UNLOCK(fromnd.ni_vp, 0); #endif fvp = fromnd.ni_vp; if (error == 0) error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); if (error != 0) { NDFREE(&fromnd, NDF_ONLY_PNBUF); vrele(fromnd.ni_dvp); vrele(fvp); goto out1; } NDINIT_ATRIGHTS(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | MPSAFE | AUDITVNODE2, pathseg, new, newfd, CAP_CREATE, td); if (fromnd.ni_vp->v_type == VDIR) tond.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&tond)) != 0) { /* Translate error code for rename("dir1", "dir2/."). */ if (error == EISDIR && fvp->v_type == VDIR) error = EINVAL; NDFREE(&fromnd, NDF_ONLY_PNBUF); vrele(fromnd.ni_dvp); vrele(fvp); vn_finished_write(mp); goto out1; } tvfslocked = NDHASGIANT(&tond); tdvp = tond.ni_dvp; tvp = tond.ni_vp; if (tvp != NULL) { if (fvp->v_type == VDIR && tvp->v_type != VDIR) { error = ENOTDIR; goto out; } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { error = EISDIR; goto out; } } if (fvp == tdvp) { error = EINVAL; goto out; } /* * If the source is the same as the destination (that is, if they * are links to the same vnode), then there is nothing to do. */ if (fvp == tvp) error = -1; #ifdef MAC else error = mac_vnode_check_rename_to(td->td_ucred, tdvp, tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); #endif out: if (!error) { error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); } else { NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); if (tvp) vput(tvp); if (tdvp == tvp) vrele(tdvp); else vput(tdvp); vrele(fromnd.ni_dvp); vrele(fvp); } vrele(tond.ni_startdir); vn_finished_write(mp); out1: if (fromnd.ni_startdir) vrele(fromnd.ni_startdir); VFS_UNLOCK_GIANT(fvfslocked); VFS_UNLOCK_GIANT(tvfslocked); if (error == -1) return (0); return (error); } /* * Make a directory file. */ #ifndef _SYS_SYSPROTO_H_ struct mkdir_args { char *path; int mode; }; #endif int sys_mkdir(td, uap) struct thread *td; register struct mkdir_args /* { char *path; int mode; } */ *uap; { return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode)); } #ifndef _SYS_SYSPROTO_H_ struct mkdirat_args { int fd; char *path; mode_t mode; }; #endif int sys_mkdirat(struct thread *td, struct mkdirat_args *uap) { return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); } int kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode) { return (kern_mkdirat(td, AT_FDCWD, path, segflg, mode)); } int kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, int mode) { struct mount *mp; struct vnode *vp; struct vattr vattr; int error; struct nameidata nd; int vfslocked; AUDIT_ARG_MODE(mode); restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, segflg, path, fd, CAP_MKDIR, td); nd.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; if (vp != NULL) { NDFREE(&nd, NDF_ONLY_PNBUF); /* * XXX namei called with LOCKPARENT but not LOCKLEAF has * the strange behaviour of leaving the vnode unlocked * if the target is the same vnode as the parent. */ if (vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(vp); VFS_UNLOCK_GIANT(vfslocked); return (EEXIST); } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } VATTR_NULL(&vattr); vattr.va_type = VDIR; vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask; #ifdef MAC error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); if (error) goto out; #endif error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); #ifdef MAC out: #endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if (!error) vput(nd.ni_vp); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Remove a directory file. */ #ifndef _SYS_SYSPROTO_H_ struct rmdir_args { char *path; }; #endif int sys_rmdir(td, uap) struct thread *td; struct rmdir_args /* { char *path; } */ *uap; { return (kern_rmdir(td, uap->path, UIO_USERSPACE)); } int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg) { return (kern_rmdirat(td, AT_FDCWD, path, pathseg)); } int kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg) { struct mount *mp; struct vnode *vp; int error; struct nameidata nd; int vfslocked; restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, fd, CAP_RMDIR, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; if (vp->v_type != VDIR) { error = ENOTDIR; goto out; } /* * No rmdir "." please. */ if (nd.ni_dvp == vp) { error = EINVAL; goto out; } /* * The root of a mounted filesystem cannot be deleted. */ if (vp->v_vflag & VV_ROOT) { error = EBUSY; goto out; } #ifdef MAC error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); if (error) goto out; #endif if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(vp); if (nd.ni_dvp == vp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); vn_finished_write(mp); out: NDFREE(&nd, NDF_ONLY_PNBUF); vput(vp); if (nd.ni_dvp == vp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); return (error); } #ifdef COMPAT_43 /* * Read a block of directory entries in a filesystem independent format. */ #ifndef _SYS_SYSPROTO_H_ struct ogetdirentries_args { int fd; char *buf; u_int count; long *basep; }; #endif int ogetdirentries(struct thread *td, struct ogetdirentries_args *uap) { long loff; int error; error = kern_ogetdirentries(td, uap, &loff); if (error == 0) error = copyout(&loff, uap->basep, sizeof(long)); return (error); } int kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, long *ploff) { struct vnode *vp; struct file *fp; struct uio auio, kuio; struct iovec aiov, kiov; struct dirent *dp, *edp; caddr_t dirbuf; int error, eofflag, readcnt, vfslocked; long loff; /* XXX arbitrary sanity limit on `count'. */ if (uap->count > 64 * 1024) return (EINVAL); if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); return (EBADF); } vp = fp->f_vnode; unionread: vfslocked = VFS_LOCK_GIANT(vp->v_mount); if (vp->v_type != VDIR) { VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (EINVAL); } aiov.iov_base = uap->buf; aiov.iov_len = uap->count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_rw = UIO_READ; auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; auio.uio_resid = uap->count; vn_lock(vp, LK_SHARED | LK_RETRY); loff = auio.uio_offset = fp->f_offset; #ifdef MAC error = mac_vnode_check_readdir(td->td_ucred, vp); if (error) { VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (error); } #endif # if (BYTE_ORDER != LITTLE_ENDIAN) if (vp->v_mount->mnt_maxsymlinklen <= 0) { error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); fp->f_offset = auio.uio_offset; } else # endif { kuio = auio; kuio.uio_iov = &kiov; kuio.uio_segflg = UIO_SYSSPACE; kiov.iov_len = uap->count; dirbuf = malloc(uap->count, M_TEMP, M_WAITOK); kiov.iov_base = dirbuf; error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, NULL, NULL); fp->f_offset = kuio.uio_offset; if (error == 0) { readcnt = uap->count - kuio.uio_resid; edp = (struct dirent *)&dirbuf[readcnt]; for (dp = (struct dirent *)dirbuf; dp < edp; ) { # if (BYTE_ORDER == LITTLE_ENDIAN) /* * The expected low byte of * dp->d_namlen is our dp->d_type. * The high MBZ byte of dp->d_namlen * is our dp->d_namlen. */ dp->d_type = dp->d_namlen; dp->d_namlen = 0; # else /* * The dp->d_type is the high byte * of the expected dp->d_namlen, * so must be zero'ed. */ dp->d_type = 0; # endif if (dp->d_reclen > 0) { dp = (struct dirent *) ((char *)dp + dp->d_reclen); } else { error = EIO; break; } } if (dp >= edp) error = uiomove(dirbuf, readcnt, &auio); } free(dirbuf, M_TEMP); } if (error) { VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (error); } if (uap->count == auio.uio_resid && (vp->v_vflag & VV_ROOT) && (vp->v_mount->mnt_flag & MNT_UNION)) { struct vnode *tvp = vp; vp = vp->v_mount->mnt_vnodecovered; VREF(vp); fp->f_vnode = vp; fp->f_data = vp; fp->f_offset = 0; vput(tvp); VFS_UNLOCK_GIANT(vfslocked); goto unionread; } VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); td->td_retval[0] = uap->count - auio.uio_resid; if (error == 0) *ploff = loff; return (error); } #endif /* COMPAT_43 */ /* * Read a block of directory entries in a filesystem independent format. */ #ifndef _SYS_SYSPROTO_H_ struct getdirentries_args { int fd; char *buf; u_int count; long *basep; }; #endif int sys_getdirentries(td, uap) struct thread *td; register struct getdirentries_args /* { int fd; char *buf; u_int count; long *basep; } */ *uap; { long base; int error; error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base); if (error) return (error); if (uap->basep != NULL) error = copyout(&base, uap->basep, sizeof(long)); return (error); } int kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, long *basep) { struct vnode *vp; struct file *fp; struct uio auio; struct iovec aiov; int vfslocked; long loff; int error, eofflag; AUDIT_ARG_FD(fd); if (count > INT_MAX) return (EINVAL); if ((error = getvnode(td->td_proc->p_fd, fd, CAP_READ | CAP_SEEK, &fp)) != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); return (EBADF); } vp = fp->f_vnode; unionread: vfslocked = VFS_LOCK_GIANT(vp->v_mount); if (vp->v_type != VDIR) { VFS_UNLOCK_GIANT(vfslocked); error = EINVAL; goto fail; } aiov.iov_base = buf; aiov.iov_len = count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_rw = UIO_READ; auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; auio.uio_resid = count; vn_lock(vp, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(vp); loff = auio.uio_offset = fp->f_offset; #ifdef MAC error = mac_vnode_check_readdir(td->td_ucred, vp); if (error == 0) #endif error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); fp->f_offset = auio.uio_offset; if (error) { VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); goto fail; } if (count == auio.uio_resid && (vp->v_vflag & VV_ROOT) && (vp->v_mount->mnt_flag & MNT_UNION)) { struct vnode *tvp = vp; vp = vp->v_mount->mnt_vnodecovered; VREF(vp); fp->f_vnode = vp; fp->f_data = vp; fp->f_offset = 0; vput(tvp); VFS_UNLOCK_GIANT(vfslocked); goto unionread; } VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); *basep = loff; td->td_retval[0] = count - auio.uio_resid; fail: fdrop(fp, td); return (error); } #ifndef _SYS_SYSPROTO_H_ struct getdents_args { int fd; char *buf; size_t count; }; #endif int sys_getdents(td, uap) struct thread *td; register struct getdents_args /* { int fd; char *buf; u_int count; } */ *uap; { struct getdirentries_args ap; ap.fd = uap->fd; ap.buf = uap->buf; ap.count = uap->count; ap.basep = NULL; return (sys_getdirentries(td, &ap)); } /* * Set the mode mask for creation of filesystem nodes. */ #ifndef _SYS_SYSPROTO_H_ struct umask_args { int newmask; }; #endif int sys_umask(td, uap) struct thread *td; struct umask_args /* { int newmask; } */ *uap; { register struct filedesc *fdp; FILEDESC_XLOCK(td->td_proc->p_fd); fdp = td->td_proc->p_fd; td->td_retval[0] = fdp->fd_cmask; fdp->fd_cmask = uap->newmask & ALLPERMS; FILEDESC_XUNLOCK(td->td_proc->p_fd); return (0); } /* * Void all references to file by ripping underlying filesystem away from * vnode. */ #ifndef _SYS_SYSPROTO_H_ struct revoke_args { char *path; }; #endif int sys_revoke(td, uap) struct thread *td; register struct revoke_args /* { char *path; } */ *uap; { struct vnode *vp; struct vattr vattr; int error; struct nameidata nd; int vfslocked; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, UIO_USERSPACE, uap->path, td); if ((error = namei(&nd)) != 0) return (error); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; NDFREE(&nd, NDF_ONLY_PNBUF); if (vp->v_type != VCHR || vp->v_rdev == NULL) { error = EINVAL; goto out; } #ifdef MAC error = mac_vnode_check_revoke(td->td_ucred, vp); if (error) goto out; #endif error = VOP_GETATTR(vp, &vattr, td->td_ucred); if (error) goto out; if (td->td_ucred->cr_uid != vattr.va_uid) { error = priv_check(td, PRIV_VFS_ADMIN); if (error) goto out; } if (vcount(vp) > 1) VOP_REVOKE(vp, REVOKEALL); out: vput(vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Convert a user file descriptor to a kernel file entry and check that, if it * is a capability, the correct rights are present. A reference on the file * entry is held upon returning. */ int getvnode(struct filedesc *fdp, int fd, cap_rights_t rights, struct file **fpp) { struct file *fp; #ifdef CAPABILITIES struct file *fp_fromcap; #endif int error; error = 0; fp = NULL; if ((fdp == NULL) || (fp = fget_unlocked(fdp, fd)) == NULL) return (EBADF); #ifdef CAPABILITIES /* * If the file descriptor is for a capability, test rights and use the * file descriptor referenced by the capability. */ error = cap_funwrap(fp, rights, &fp_fromcap); if (error) { fdrop(fp, curthread); return (error); } if (fp != fp_fromcap) { fhold(fp_fromcap); fdrop(fp, curthread); fp = fp_fromcap; } #endif /* CAPABILITIES */ if (fp->f_vnode == NULL) { fdrop(fp, curthread); return (EINVAL); } *fpp = fp; return (0); } /* * Get an (NFS) file handle. */ #ifndef _SYS_SYSPROTO_H_ struct lgetfh_args { char *fname; fhandle_t *fhp; }; #endif int sys_lgetfh(td, uap) struct thread *td; register struct lgetfh_args *uap; { struct nameidata nd; fhandle_t fh; register struct vnode *vp; int vfslocked; int error; error = priv_check(td, PRIV_VFS_GETFH); if (error) return (error); NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, UIO_USERSPACE, uap->fname, td); error = namei(&nd); if (error) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; bzero(&fh, sizeof(fh)); fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; error = VOP_VPTOFH(vp, &fh.fh_fid); vput(vp); VFS_UNLOCK_GIANT(vfslocked); if (error) return (error); error = copyout(&fh, uap->fhp, sizeof (fh)); return (error); } #ifndef _SYS_SYSPROTO_H_ struct getfh_args { char *fname; fhandle_t *fhp; }; #endif int sys_getfh(td, uap) struct thread *td; register struct getfh_args *uap; { struct nameidata nd; fhandle_t fh; register struct vnode *vp; int vfslocked; int error; error = priv_check(td, PRIV_VFS_GETFH); if (error) return (error); NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, UIO_USERSPACE, uap->fname, td); error = namei(&nd); if (error) return (error); vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; bzero(&fh, sizeof(fh)); fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; error = VOP_VPTOFH(vp, &fh.fh_fid); vput(vp); VFS_UNLOCK_GIANT(vfslocked); if (error) return (error); error = copyout(&fh, uap->fhp, sizeof (fh)); return (error); } /* * syscall for the rpc.lockd to use to translate a NFS file handle into an * open descriptor. * * warning: do not remove the priv_check() call or this becomes one giant * security hole. */ #ifndef _SYS_SYSPROTO_H_ struct fhopen_args { const struct fhandle *u_fhp; int flags; }; #endif int sys_fhopen(td, uap) struct thread *td; struct fhopen_args /* { const struct fhandle *u_fhp; int flags; } */ *uap; { struct proc *p = td->td_proc; struct mount *mp; struct vnode *vp; struct fhandle fhp; struct vattr vat; struct vattr *vap = &vat; struct flock lf; struct file *fp; register struct filedesc *fdp = p->p_fd; int fmode, error, type; accmode_t accmode; struct file *nfp; int vfslocked; int indx; error = priv_check(td, PRIV_VFS_FHOPEN); if (error) return (error); fmode = FFLAGS(uap->flags); /* why not allow a non-read/write open for our lockd? */ if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) return (EINVAL); error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); if (error) return(error); /* find the mount point */ mp = vfs_busyfs(&fhp.fh_fsid); if (mp == NULL) return (ESTALE); vfslocked = VFS_LOCK_GIANT(mp); /* now give me my vnode, it gets returned to me locked */ error = VFS_FHTOVP(mp, &fhp.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); if (error) goto out; /* * from now on we have to make sure not * to forget about the vnode * any error that causes an abort must vput(vp) * just set error = err and 'goto bad;'. */ /* * from vn_open */ if (vp->v_type == VLNK) { error = EMLINK; goto bad; } if (vp->v_type == VSOCK) { error = EOPNOTSUPP; goto bad; } if (vp->v_type != VDIR && fmode & O_DIRECTORY) { error = ENOTDIR; goto bad; } accmode = 0; if (fmode & (FWRITE | O_TRUNC)) { if (vp->v_type == VDIR) { error = EISDIR; goto bad; } error = vn_writechk(vp); if (error) goto bad; accmode |= VWRITE; } if (fmode & FREAD) accmode |= VREAD; if ((fmode & O_APPEND) && (fmode & FWRITE)) accmode |= VAPPEND; #ifdef MAC error = mac_vnode_check_open(td->td_ucred, vp, accmode); if (error) goto bad; #endif if (accmode) { error = VOP_ACCESS(vp, accmode, td->td_ucred, td); if (error) goto bad; } if (fmode & O_TRUNC) { vfs_ref(mp); VOP_UNLOCK(vp, 0); /* XXX */ if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) { vrele(vp); vfs_rel(mp); goto out; } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* XXX */ vfs_rel(mp); #ifdef MAC /* * We don't yet have fp->f_cred, so use td->td_ucred, which * should be right. */ error = mac_vnode_check_write(td->td_ucred, td->td_ucred, vp); if (error == 0) { #endif VATTR_NULL(vap); vap->va_size = 0; error = VOP_SETATTR(vp, vap, td->td_ucred); #ifdef MAC } #endif vn_finished_write(mp); if (error) goto bad; } error = VOP_OPEN(vp, fmode, td->td_ucred, td, NULL); if (error) goto bad; if (fmode & FWRITE) vp->v_writecount++; /* * end of vn_open code */ if ((error = falloc(td, &nfp, &indx, fmode)) != 0) { if (fmode & FWRITE) vp->v_writecount--; goto bad; } /* An extra reference on `nfp' has been held for us by falloc(). */ fp = nfp; nfp->f_vnode = vp; finit(nfp, fmode & FMASK, DTYPE_VNODE, vp, &vnops); if (fmode & (O_EXLOCK | O_SHLOCK)) { lf.l_whence = SEEK_SET; lf.l_start = 0; lf.l_len = 0; if (fmode & O_EXLOCK) lf.l_type = F_WRLCK; else lf.l_type = F_RDLCK; type = F_FLOCK; if ((fmode & FNONBLOCK) == 0) type |= F_WAIT; VOP_UNLOCK(vp, 0); if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { /* * The lock request failed. Normally close the * descriptor but handle the case where someone might * have dup()d or close()d it when we weren't looking. */ fdclose(fdp, fp, indx, td); /* * release our private reference */ fdrop(fp, td); goto out; } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); atomic_set_int(&fp->f_flag, FHASLOCK); } VOP_UNLOCK(vp, 0); fdrop(fp, td); VFS_UNLOCK_GIANT(vfslocked); td->td_retval[0] = indx; return (0); bad: vput(vp); out: VFS_UNLOCK_GIANT(vfslocked); return (error); } /* * Stat an (NFS) file handle. */ #ifndef _SYS_SYSPROTO_H_ struct fhstat_args { struct fhandle *u_fhp; struct stat *sb; }; #endif int sys_fhstat(td, uap) struct thread *td; register struct fhstat_args /* { struct fhandle *u_fhp; struct stat *sb; } */ *uap; { struct stat sb; fhandle_t fh; struct mount *mp; struct vnode *vp; int vfslocked; int error; error = priv_check(td, PRIV_VFS_FHSTAT); if (error) return (error); error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); if (error) return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); vfslocked = VFS_LOCK_GIANT(mp); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); if (error) { VFS_UNLOCK_GIANT(vfslocked); return (error); } error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); vput(vp); VFS_UNLOCK_GIANT(vfslocked); if (error) return (error); error = copyout(&sb, uap->sb, sizeof(sb)); return (error); } /* * Implement fstatfs() for (NFS) file handles. */ #ifndef _SYS_SYSPROTO_H_ struct fhstatfs_args { struct fhandle *u_fhp; struct statfs *buf; }; #endif int sys_fhstatfs(td, uap) struct thread *td; struct fhstatfs_args /* { struct fhandle *u_fhp; struct statfs *buf; } */ *uap; { struct statfs sf; fhandle_t fh; int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); if (error) return (error); error = kern_fhstatfs(td, fh, &sf); if (error) return (error); return (copyout(&sf, uap->buf, sizeof(sf))); } int kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) { struct statfs *sp; struct mount *mp; struct vnode *vp; int vfslocked; int error; error = priv_check(td, PRIV_VFS_FHSTATFS); if (error) return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); vfslocked = VFS_LOCK_GIANT(mp); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); if (error) { vfs_unbusy(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } vput(vp); error = prison_canseemount(td->td_ucred, mp); if (error) goto out; #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); if (error) goto out; #endif /* * Set these in case the underlying filesystem fails to do so. */ sp = &mp->mnt_stat; sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp); if (error == 0) *buf = *sp; out: vfs_unbusy(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); } int kern_posix_fallocate(struct thread *td, int fd, off_t offset, off_t len) { struct file *fp; struct mount *mp; struct vnode *vp; off_t olen, ooffset; int error, vfslocked; fp = NULL; vfslocked = 0; error = fget(td, fd, CAP_WRITE, &fp); if (error != 0) goto out; switch (fp->f_type) { case DTYPE_VNODE: break; case DTYPE_PIPE: case DTYPE_FIFO: error = ESPIPE; goto out; default: error = ENODEV; goto out; } if ((fp->f_flag & FWRITE) == 0) { error = EBADF; goto out; } vp = fp->f_vnode; if (vp->v_type != VREG) { error = ENODEV; goto out; } if (offset < 0 || len <= 0) { error = EINVAL; goto out; } /* Check for wrap. */ if (offset > OFF_MAX - len) { error = EFBIG; goto out; } /* Allocating blocks may take a long time, so iterate. */ for (;;) { olen = len; ooffset = offset; bwillwrite(); vfslocked = VFS_LOCK_GIANT(vp->v_mount); mp = NULL; error = vn_start_write(vp, &mp, V_WAIT | PCATCH); if (error != 0) { VFS_UNLOCK_GIANT(vfslocked); break; } error = vn_lock(vp, LK_EXCLUSIVE); if (error != 0) { vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); break; } #ifdef MAC error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp); if (error == 0) #endif error = VOP_ALLOCATE(vp, &offset, &len); VOP_UNLOCK(vp, 0); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); if (olen + ooffset != offset + len) { panic("offset + len changed from %jx/%jx to %jx/%jx", ooffset, olen, offset, len); } if (error != 0 || len == 0) break; KASSERT(olen > len, ("Iteration did not make progress?")); maybe_yield(); } out: if (fp != NULL) fdrop(fp, td); return (error); } int sys_posix_fallocate(struct thread *td, struct posix_fallocate_args *uap) { return (kern_posix_fallocate(td, uap->fd, uap->offset, uap->len)); } /* * Unlike madvise(2), we do not make a best effort to remember every * possible caching hint. Instead, we remember the last setting with * the exception that we will allow POSIX_FADV_NORMAL to adjust the * region of any current setting. */ int kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, int advice) { struct fadvise_info *fa, *new; struct file *fp; struct vnode *vp; off_t end; int error; if (offset < 0 || len < 0 || offset > OFF_MAX - len) return (EINVAL); switch (advice) { case POSIX_FADV_SEQUENTIAL: case POSIX_FADV_RANDOM: case POSIX_FADV_NOREUSE: new = malloc(sizeof(*fa), M_FADVISE, M_WAITOK); break; case POSIX_FADV_NORMAL: case POSIX_FADV_WILLNEED: case POSIX_FADV_DONTNEED: new = NULL; break; default: return (EINVAL); } /* XXX: CAP_POSIX_FADVISE? */ error = fget(td, fd, 0, &fp); if (error != 0) goto out; switch (fp->f_type) { case DTYPE_VNODE: break; case DTYPE_PIPE: case DTYPE_FIFO: error = ESPIPE; goto out; default: error = ENODEV; goto out; } vp = fp->f_vnode; if (vp->v_type != VREG) { error = ENODEV; goto out; } if (len == 0) end = OFF_MAX; else end = offset + len - 1; switch (advice) { case POSIX_FADV_SEQUENTIAL: case POSIX_FADV_RANDOM: case POSIX_FADV_NOREUSE: /* * Try to merge any existing non-standard region with * this new region if possible, otherwise create a new * non-standard region for this request. */ mtx_pool_lock(mtxpool_sleep, fp); fa = fp->f_advice; if (fa != NULL && fa->fa_advice == advice && ((fa->fa_start <= end && fa->fa_end >= offset) || (end != OFF_MAX && fa->fa_start == end + 1) || (fa->fa_end != OFF_MAX && fa->fa_end + 1 == offset))) { if (offset < fa->fa_start) fa->fa_start = offset; if (end > fa->fa_end) fa->fa_end = end; } else { new->fa_advice = advice; new->fa_start = offset; new->fa_end = end; fp->f_advice = new; new = fa; } mtx_pool_unlock(mtxpool_sleep, fp); break; case POSIX_FADV_NORMAL: /* * If a the "normal" region overlaps with an existing * non-standard region, trim or remove the * non-standard region. */ mtx_pool_lock(mtxpool_sleep, fp); fa = fp->f_advice; if (fa != NULL) { if (offset <= fa->fa_start && end >= fa->fa_end) { new = fa; fp->f_advice = NULL; } else if (offset <= fa->fa_start && end >= fa->fa_start) fa->fa_start = end + 1; else if (offset <= fa->fa_end && end >= fa->fa_end) fa->fa_end = offset - 1; else if (offset >= fa->fa_start && end <= fa->fa_end) { /* * If the "normal" region is a middle * portion of the existing * non-standard region, just remove * the whole thing rather than picking * one side or the other to * preserve. */ new = fa; fp->f_advice = NULL; } } mtx_pool_unlock(mtxpool_sleep, fp); break; case POSIX_FADV_WILLNEED: case POSIX_FADV_DONTNEED: error = VOP_ADVISE(vp, offset, end, advice); break; } out: if (fp != NULL) fdrop(fp, td); free(new, M_FADVISE); return (error); } int sys_posix_fadvise(struct thread *td, struct posix_fadvise_args *uap) { return (kern_posix_fadvise(td, uap->fd, uap->offset, uap->len, uap->advice)); }