diff options
author | jhb <jhb@FreeBSD.org> | 2005-02-07 22:02:18 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2005-02-07 22:02:18 +0000 |
commit | 4a479b242427dd7291f1456f605ae37513c1ceaf (patch) | |
tree | 5d16fdc572b765e011ca89f203e7653f1ba5a0a8 /sys/i386 | |
parent | b03a8bb21b2ea1fa1d440565c2ee55a7391e1c18 (diff) | |
download | FreeBSD-src-4a479b242427dd7291f1456f605ae37513c1ceaf.zip FreeBSD-src-4a479b242427dd7291f1456f605ae37513c1ceaf.tar.gz |
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/ibcs2/ibcs2_fcntl.c | 52 | ||||
-rw-r--r-- | sys/i386/ibcs2/ibcs2_misc.c | 272 | ||||
-rw-r--r-- | sys/i386/ibcs2/ibcs2_msg.c | 28 | ||||
-rw-r--r-- | sys/i386/ibcs2/ibcs2_other.c | 2 | ||||
-rw-r--r-- | sys/i386/ibcs2/ibcs2_stat.c | 91 | ||||
-rw-r--r-- | sys/i386/ibcs2/ibcs2_util.c | 132 | ||||
-rw-r--r-- | sys/i386/ibcs2/ibcs2_util.h | 20 | ||||
-rw-r--r-- | sys/i386/ibcs2/ibcs2_xenix.c | 47 |
8 files changed, 268 insertions, 376 deletions
diff --git a/sys/i386/ibcs2/ibcs2_fcntl.c b/sys/i386/ibcs2/ibcs2_fcntl.c index 1b02fbc..fcdc714 100644 --- a/sys/i386/ibcs2/ibcs2_fcntl.c +++ b/sys/i386/ibcs2/ibcs2_fcntl.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include <sys/file.h> #include <sys/filedesc.h> #include <sys/lock.h> +#include <sys/malloc.h> #include <sys/mutex.h> #include <sys/syscallsubr.h> #include <sys/sysproto.h> @@ -175,24 +176,27 @@ ibcs2_open(td, uap) struct thread *td; struct ibcs2_open_args *uap; { - struct proc *p = td->td_proc; - int noctty = uap->flags & IBCS2_O_NOCTTY; - int ret; - caddr_t sg = stackgap_init(); + struct proc *p; + char *path; + int flags, noctty, ret; - uap->flags = cvt_o_flags(uap->flags); + p = td->td_proc; + noctty = uap->flags & IBCS2_O_NOCTTY; + flags = cvt_o_flags(uap->flags); if (uap->flags & O_CREAT) - CHECKALTCREAT(td, &sg, uap->path); + CHECKALTCREAT(td, uap->path, &path); else - CHECKALTEXIST(td, &sg, uap->path); - ret = open(td, (struct open_args *)uap); + CHECKALTEXIST(td, uap->path, &path); + ret = kern_open(td, path, UIO_SYSSPACE, flags, uap->mode); #ifdef SPX_HACK if (ret == ENXIO) { - if (!strcmp(uap->path, "/compat/ibcs2/dev/spx")) - ret = spx_open(td, uap); + 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; @@ -217,15 +221,15 @@ int ibcs2_creat(td, uap) struct thread *td; struct ibcs2_creat_args *uap; -{ - struct open_args cup; - caddr_t sg = stackgap_init(); +{ + char *path; + int error; - CHECKALTCREAT(td, &sg, uap->path); - cup.path = uap->path; - cup.mode = uap->mode; - cup.flags = O_WRONLY | O_CREAT | O_TRUNC; - return open(td, &cup); + 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 @@ -233,13 +237,13 @@ ibcs2_access(td, uap) struct thread *td; struct ibcs2_access_args *uap; { - struct access_args cup; - caddr_t sg = stackgap_init(); + char *path; + int error; - CHECKALTEXIST(td, &sg, uap->path); - cup.path = uap->path; - cup.flags = uap->flags; - return access(td, &cup); + CHECKALTEXIST(td, uap->path, &path); + error = kern_access(td, path, UIO_SYSSPACE, uap->flags); + free(path, M_TEMP); + return (error); } int diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c index 99d9ec7..d29946f 100644 --- a/sys/i386/ibcs2/ibcs2_misc.c +++ b/sys/i386/ibcs2/ibcs2_misc.c @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include <sys/dirent.h> #include <sys/fcntl.h> #include <sys/filedesc.h> +#include <sys/imgact.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/mac.h> @@ -196,14 +197,18 @@ ibcs2_execv(td, uap) struct thread *td; struct ibcs2_execv_args *uap; { - struct execve_args ea; - caddr_t sg = stackgap_init(); + struct image_args eargs; + char *path; + int error; - CHECKALTEXIST(td, &sg, uap->path); - ea.fname = uap->path; - ea.argv = uap->argp; - ea.envv = NULL; - return execve(td, &ea); + CHECKALTEXIST(td, uap->path, &path); + + error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, NULL); + free(path, M_TEMP); + if (error == 0) + error = kern_execve(td, &eargs, NULL); + exec_free_args(&eargs); + return (error); } int @@ -211,9 +216,19 @@ ibcs2_execve(td, uap) struct thread *td; struct ibcs2_execve_args *uap; { - caddr_t sg = stackgap_init(); - CHECKALTEXIST(td, &sg, uap->path); - return execve(td, (struct execve_args *)uap); + struct image_args eargs; + char *path; + int error; + + CHECKALTEXIST(td, uap->path, &path); + + error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, + uap->envp); + free(path, M_TEMP); + if (error == 0) + error = kern_execve(td, &eargs, NULL); + exec_free_args(&eargs); + return (error); } int @@ -623,21 +638,16 @@ ibcs2_mknod(td, uap) struct thread *td; struct ibcs2_mknod_args *uap; { - caddr_t sg = stackgap_init(); - - CHECKALTCREAT(td, &sg, uap->path); - if (S_ISFIFO(uap->mode)) { - struct mkfifo_args ap; - ap.path = uap->path; - ap.mode = uap->mode; - return mkfifo(td, &ap); - } else { - struct mknod_args ap; - ap.path = uap->path; - ap.mode = uap->mode; - ap.dev = uap->dev; - return mknod(td, &ap); - } + char *path; + int error; + + CHECKALTCREAT(td, uap->path, &path); + if (S_ISFIFO(uap->mode)) + error = kern_mkfifo(td, path, UIO_SYSSPACE, uap->mode); + else + error = kern_mknod(td, path, UIO_SYSSPACE, uap->mode, uap->dev); + free(path, M_TEMP); + return (error); } int @@ -748,8 +758,14 @@ ibcs2_pathconf(td, uap) struct thread *td; struct ibcs2_pathconf_args *uap; { + char *path; + int error; + + CHECKALTEXIST(td, uap->path, &path); uap->name++; /* iBCS2 _PC_* defines are offset by one */ - return pathconf(td, (struct pathconf_args *)uap); + error = kern_pathconf(td, path, UIO_SYSSPACE, uap->name); + free(path, M_TEMP); + return (error); } int @@ -833,27 +849,19 @@ ibcs2_alarm(td, uap) struct thread *td; struct ibcs2_alarm_args *uap; { + struct itimerval itv, oitv; int error; - struct itimerval *itp, *oitp; - struct setitimer_args sa; - caddr_t sg = stackgap_init(); - itp = stackgap_alloc(&sg, sizeof(*itp)); - oitp = stackgap_alloc(&sg, sizeof(*oitp)); - timevalclear(&itp->it_interval); - itp->it_value.tv_sec = uap->sec; - itp->it_value.tv_usec = 0; - - sa.which = ITIMER_REAL; - sa.itv = itp; - sa.oitv = oitp; - error = setitimer(td, &sa); + timevalclear(&itv.it_interval); + itv.it_value.tv_sec = uap->sec; + itv.it_value.tv_usec = 0; + error = kern_setitimer(td, ITIMER_REAL, &itv, &oitv); if (error) - return error; - if (oitp->it_value.tv_usec) - oitp->it_value.tv_sec++; - td->td_retval[0] = oitp->it_value.tv_sec; - return 0; + return (error); + if (oitv.it_value.tv_usec != 0) + oitv.it_value.tv_sec++; + td->td_retval[0] = oitv.it_value.tv_sec; + return (0); } int @@ -861,34 +869,29 @@ ibcs2_times(td, uap) struct thread *td; struct ibcs2_times_args *uap; { - int error; - struct getrusage_args ga; + struct rusage ru; + struct timeval t; struct tms tms; - struct timeval t; - caddr_t sg = stackgap_init(); - struct rusage *ru = stackgap_alloc(&sg, sizeof(*ru)); + int error; + #define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz)) - ga.who = RUSAGE_SELF; - ga.rusage = ru; - error = getrusage(td, &ga); + error = kern_getrusage(td, RUSAGE_SELF, &ru); if (error) - return error; - tms.tms_utime = CONVTCK(ru->ru_utime); - tms.tms_stime = CONVTCK(ru->ru_stime); + return (error); + tms.tms_utime = CONVTCK(ru.ru_utime); + tms.tms_stime = CONVTCK(ru.ru_stime); - ga.who = RUSAGE_CHILDREN; - error = getrusage(td, &ga); + error = kern_getrusage(td, RUSAGE_CHILDREN, &ru); if (error) - return error; - tms.tms_cutime = CONVTCK(ru->ru_utime); - tms.tms_cstime = CONVTCK(ru->ru_stime); + return (error); + tms.tms_cutime = CONVTCK(ru.ru_utime); + tms.tms_cstime = CONVTCK(ru.ru_stime); microtime(&t); - td->td_retval[0] = CONVTCK(t); + td->td_retval[0] = CONVTCK(t); - return copyout((caddr_t)&tms, (caddr_t)uap->tp, - sizeof(struct tms)); + return (copyout(&tms, uap->tp, sizeof(struct tms))); } int @@ -916,30 +919,27 @@ ibcs2_utime(td, uap) struct thread *td; struct ibcs2_utime_args *uap; { + struct ibcs2_utimbuf ubuf; + struct timeval tbuf[2], *tp; + char *path; int error; - struct utimes_args sa; - struct timeval *tp; - caddr_t sg = stackgap_init(); - CHECKALTEXIST(td, &sg, uap->path); - sa.path = uap->path; if (uap->buf) { - struct ibcs2_utimbuf ubuf; - - if ((error = copyin((caddr_t)uap->buf, (caddr_t)&ubuf, - sizeof(ubuf))) != 0) - return error; - sa.tptr = stackgap_alloc(&sg, - 2 * sizeof(struct timeval *)); - tp = (struct timeval *)sa.tptr; - tp->tv_sec = ubuf.actime; - tp->tv_usec = 0; - tp++; - tp->tv_sec = ubuf.modtime; - tp->tv_usec = 0; + error = copyin(uap->buf, &ubuf, sizeof(ubuf)); + if (error) + return (error); + tbuf[0].tv_sec = ubuf.actime; + tbuf[0].tv_usec = 0; + tbuf[1].tv_sec = ubuf.modtime; + tbuf[1].tv_usec = 0; + tp = tbuf; } else - sa.tptr = NULL; - return utimes(td, &sa); + tp = NULL; + + CHECKALTEXIST(td, uap->path, &path); + error = kern_utimes(td, path, UIO_SYSSPACE, tp, UIO_SYSSPACE); + free(path, M_TEMP); + return (error); } int @@ -1109,10 +1109,13 @@ ibcs2_unlink(td, uap) struct thread *td; struct ibcs2_unlink_args *uap; { - caddr_t sg = stackgap_init(); + char *path; + int error; - CHECKALTEXIST(td, &sg, uap->path); - return unlink(td, (struct unlink_args *)uap); + CHECKALTEXIST(td, uap->path, &path); + error = kern_unlink(td, path, UIO_SYSSPACE); + free(path, M_TEMP); + return (error); } int @@ -1120,10 +1123,13 @@ ibcs2_chdir(td, uap) struct thread *td; struct ibcs2_chdir_args *uap; { - caddr_t sg = stackgap_init(); + char *path; + int error; - CHECKALTEXIST(td, &sg, uap->path); - return chdir(td, (struct chdir_args *)uap); + CHECKALTEXIST(td, uap->path, &path); + error = kern_chdir(td, path, UIO_SYSSPACE); + free(path, M_TEMP); + return (error); } int @@ -1131,10 +1137,13 @@ ibcs2_chmod(td, uap) struct thread *td; struct ibcs2_chmod_args *uap; { - caddr_t sg = stackgap_init(); + char *path; + int error; - CHECKALTEXIST(td, &sg, uap->path); - return chmod(td, (struct chmod_args *)uap); + CHECKALTEXIST(td, uap->path, &path); + error = kern_chmod(td, path, UIO_SYSSPACE, uap->mode); + free(path, M_TEMP); + return (error); } int @@ -1142,10 +1151,13 @@ ibcs2_chown(td, uap) struct thread *td; struct ibcs2_chown_args *uap; { - caddr_t sg = stackgap_init(); + char *path; + int error; - CHECKALTEXIST(td, &sg, uap->path); - return chown(td, (struct chown_args *)uap); + CHECKALTEXIST(td, uap->path, &path); + error = kern_chown(td, path, UIO_SYSSPACE, uap->uid, uap->gid); + free(path, M_TEMP); + return (error); } int @@ -1153,10 +1165,13 @@ ibcs2_rmdir(td, uap) struct thread *td; struct ibcs2_rmdir_args *uap; { - caddr_t sg = stackgap_init(); + char *path; + int error; - CHECKALTEXIST(td, &sg, uap->path); - return rmdir(td, (struct rmdir_args *)uap); + CHECKALTEXIST(td, uap->path, &path); + error = kern_rmdir(td, path, UIO_SYSSPACE); + free(path, M_TEMP); + return (error); } int @@ -1164,10 +1179,13 @@ ibcs2_mkdir(td, uap) struct thread *td; struct ibcs2_mkdir_args *uap; { - caddr_t sg = stackgap_init(); + char *path; + int error; - CHECKALTCREAT(td, &sg, uap->path); - return mkdir(td, (struct mkdir_args *)uap); + CHECKALTEXIST(td, uap->path, &path); + error = kern_mkdir(td, path, UIO_SYSSPACE, uap->mode); + free(path, M_TEMP); + return (error); } int @@ -1175,11 +1193,24 @@ ibcs2_symlink(td, uap) struct thread *td; struct ibcs2_symlink_args *uap; { - caddr_t sg = stackgap_init(); + char *path, *link; + int error; - CHECKALTEXIST(td, &sg, uap->path); - CHECKALTCREAT(td, &sg, uap->link); - return symlink(td, (struct symlink_args *)uap); + CHECKALTEXIST(td, uap->path, &path); + + /* + * Have to expand CHECKALTCREAT() so that 'path' can be freed on + * errors. + */ + error = ibcs2_emul_find(td, uap->link, UIO_USERSPACE, &link, 1); + if (link == NULL) { + free(path, M_TEMP); + return (error); + } + error = kern_symlink(td, path, link, UIO_SYSSPACE); + free(path, M_TEMP); + free(link, M_TEMP); + return (error); } int @@ -1187,11 +1218,24 @@ ibcs2_rename(td, uap) struct thread *td; struct ibcs2_rename_args *uap; { - caddr_t sg = stackgap_init(); + char *from, *to; + int error; + + CHECKALTEXIST(td, uap->from, &from); - CHECKALTEXIST(td, &sg, uap->from); - CHECKALTCREAT(td, &sg, uap->to); - return rename(td, (struct rename_args *)uap); + /* + * Have to expand CHECKALTCREAT() so that 'from' can be freed on + * errors. + */ + error = ibcs2_emul_find(td, uap->to, UIO_USERSPACE, &to, 1); + if (link == NULL) { + free(from, M_TEMP); + return (error); + } + error = kern_rename(td, from, to, UIO_SYSSPACE); + free(from, M_TEMP); + free(to, M_TEMP); + return (error); } int @@ -1199,8 +1243,12 @@ ibcs2_readlink(td, uap) struct thread *td; struct ibcs2_readlink_args *uap; { - caddr_t sg = stackgap_init(); + char *path; + int error; - CHECKALTEXIST(td, &sg, uap->path); - return readlink(td, (struct readlink_args *) uap); + CHECKALTEXIST(td, uap->path, &path); + error = kern_readlink(td, path, UIO_SYSSPACE, uap->buf, UIO_USERSPACE, + uap->count); + free(path, M_TEMP); + return (error); } diff --git a/sys/i386/ibcs2/ibcs2_msg.c b/sys/i386/ibcs2/ibcs2_msg.c index 0072856..f17befc 100644 --- a/sys/i386/ibcs2/ibcs2_msg.c +++ b/sys/i386/ibcs2/ibcs2_msg.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> +#include <sys/syscallsubr.h> #include <sys/sysproto.h> #include <i386/ibcs2/ibcs2_types.h> @@ -63,11 +64,10 @@ ibcs2_poll(td, uap) struct thread *td; struct ibcs2_poll_args *uap; { - int error, i; + int error, i, nfds; fd_set *readfds, *writefds, *exceptfds; - struct timeval *timeout; + struct timeval timeout, *tp; struct ibcs2_poll conv; - struct select_args tmp_select; caddr_t sg = stackgap_init(); if (uap->nfds > FD_SETSIZE) @@ -75,24 +75,19 @@ ibcs2_poll(td, uap) readfds = stackgap_alloc(&sg, sizeof(fd_set *)); writefds = stackgap_alloc(&sg, sizeof(fd_set *)); exceptfds = stackgap_alloc(&sg, sizeof(fd_set *)); - timeout = stackgap_alloc(&sg, sizeof(struct timeval *)); FD_ZERO(readfds); FD_ZERO(writefds); FD_ZERO(exceptfds); if (uap->timeout == -1) - timeout = NULL; + tp = NULL; else { - timeout->tv_usec = (uap->timeout % 1000)*1000; - timeout->tv_sec = uap->timeout / 1000; + timeout.tv_usec = (uap->timeout % 1000)*1000; + timeout.tv_sec = uap->timeout / 1000; + tp = &timeout; } - tmp_select.nd = 0; - tmp_select.in = readfds; - tmp_select.ou = writefds; - tmp_select.ex = exceptfds; - tmp_select.tv = timeout; - + nfds = 0; for (i = 0; i < uap->nfds; i++) { if ((error = copyin(uap->fds + i*sizeof(struct ibcs2_poll), &conv, sizeof(conv))) != 0) @@ -100,15 +95,16 @@ ibcs2_poll(td, uap) conv.revents = 0; if (conv.fd < 0 || conv.fd > FD_SETSIZE) continue; - if (conv.fd >= tmp_select.nd) - tmp_select.nd = conv.fd + 1; + if (conv.fd >= nfds) + nfds = conv.fd + 1; if (conv.events & IBCS2_READPOLL) FD_SET(conv.fd, readfds); if (conv.events & IBCS2_WRITEPOLL) FD_SET(conv.fd, writefds); FD_SET(conv.fd, exceptfds); } - if ((error = select(td, &tmp_select)) != 0) + error = kern_select(td, nfds, readfds, writefds, exceptfds, tp); + if (error != 0) return error; if (td->td_retval[0] == 0) return 0; diff --git a/sys/i386/ibcs2/ibcs2_other.c b/sys/i386/ibcs2/ibcs2_other.c index b40d43b..2a8c21d 100644 --- a/sys/i386/ibcs2/ibcs2_other.c +++ b/sys/i386/ibcs2/ibcs2_other.c @@ -82,7 +82,7 @@ ibcs2_lseek(struct thread *td, register struct ibcs2_lseek_args *uap) #include <sys/un.h> int -spx_open(struct thread *td, void *uap) +spx_open(struct thread *td) { struct socket_args sock; struct connect_args conn; diff --git a/sys/i386/ibcs2/ibcs2_stat.c b/sys/i386/ibcs2/ibcs2_stat.c index c4a8bca..9253071 100644 --- a/sys/i386/ibcs2/ibcs2_stat.c +++ b/sys/i386/ibcs2/ibcs2_stat.c @@ -38,7 +38,9 @@ __FBSDID("$FreeBSD$"); #include <sys/jail.h> #include <sys/kernel.h> #include <sys/mount.h> +#include <sys/malloc.h> #include <sys/vnode.h> +#include <sys/syscallsubr.h> #include <sys/sysctl.h> #include <sys/sysproto.h> @@ -105,24 +107,16 @@ ibcs2_statfs(td, uap) struct thread *td; struct ibcs2_statfs_args *uap; { - register struct mount *mp; - register struct statfs *sp; + struct statfs sf; + char *path; int error; - struct nameidata nd; - caddr_t sg = stackgap_init(); - CHECKALTEXIST(td, &sg, uap->path); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td); - if ((error = namei(&nd)) != 0) + CHECKALTEXIST(td, uap->path, &path); + error = kern_statfs(td, path, UIO_SYSSPACE, &sf); + free(path, M_TEMP); + if (error) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - mp = nd.ni_vp->v_mount; - sp = &mp->mnt_stat; - vrele(nd.ni_vp); - if ((error = VFS_STATFS(mp, sp, td)) != 0) - return (error); - sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - return cvt_statfs(sp, (caddr_t)uap->buf, uap->len); + return cvt_statfs(&sf, (caddr_t)uap->buf, uap->len); } int @@ -130,21 +124,13 @@ ibcs2_fstatfs(td, uap) struct thread *td; struct ibcs2_fstatfs_args *uap; { - struct file *fp; - struct mount *mp; - register struct statfs *sp; + struct statfs sf; int error; - if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) - return (error); - mp = fp->f_vnode->v_mount; - sp = &mp->mnt_stat; - error = VFS_STATFS(mp, sp, td); - fdrop(fp, td); - if (error != 0) + error = kern_fstatfs(td, uap->fd, &sf); + if (error) return (error); - sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - return cvt_statfs(sp, (caddr_t)uap->buf, uap->len); + return cvt_statfs(&sf, (caddr_t)uap->buf, uap->len); } int @@ -152,21 +138,17 @@ ibcs2_stat(td, uap) struct thread *td; struct ibcs2_stat_args *uap; { - struct stat st; struct ibcs2_stat ibcs2_st; - struct stat_args cup; + struct stat st; + char *path; int error; - caddr_t sg = stackgap_init(); - CHECKALTEXIST(td, &sg, uap->path); - cup.path = uap->path; - cup.ub = stackgap_alloc(&sg, sizeof(st)); + CHECKALTEXIST(td, uap->path, &path); - if ((error = stat(td, &cup)) != 0) - return error; - - if ((error = copyin(cup.ub, &st, sizeof(st))) != 0) - return error; + error = kern_stat(td, path, UIO_SYSSPACE, &st); + free(path, M_TEMP); + if (error) + return (error); bsd_stat2ibcs_stat(&st, &ibcs2_st); return copyout((caddr_t)&ibcs2_st, (caddr_t)uap->st, ibcs2_stat_len); @@ -177,21 +159,17 @@ ibcs2_lstat(td, uap) struct thread *td; struct ibcs2_lstat_args *uap; { - struct stat st; struct ibcs2_stat ibcs2_st; - struct lstat_args cup; + struct stat st; + char *path; int error; - caddr_t sg = stackgap_init(); - CHECKALTEXIST(td, &sg, uap->path); - cup.path = uap->path; - cup.ub = stackgap_alloc(&sg, sizeof(st)); + CHECKALTEXIST(td, uap->path, &path); - if ((error = lstat(td, &cup)) != 0) - return error; - - if ((error = copyin(cup.ub, &st, sizeof(st))) != 0) - return error; + error = kern_lstat(td, path, UIO_SYSSPACE, &st); + free(path, M_TEMP); + if (error) + return (error); bsd_stat2ibcs_stat(&st, &ibcs2_st); return copyout((caddr_t)&ibcs2_st, (caddr_t)uap->st, ibcs2_stat_len); @@ -202,20 +180,13 @@ ibcs2_fstat(td, uap) struct thread *td; struct ibcs2_fstat_args *uap; { - struct stat st; struct ibcs2_stat ibcs2_st; - struct fstat_args cup; + struct stat st; int error; - caddr_t sg = stackgap_init(); - cup.fd = uap->fd; - cup.sb = stackgap_alloc(&sg, sizeof(st)); - - if ((error = fstat(td, &cup)) != 0) - return error; - - if ((error = copyin(cup.sb, &st, sizeof(st))) != 0) - return error; + error = kern_fstat(td, uap->fd, &st); + if (error) + return (error); bsd_stat2ibcs_stat(&st, &ibcs2_st); return copyout((caddr_t)&ibcs2_st, (caddr_t)uap->st, ibcs2_stat_len); diff --git a/sys/i386/ibcs2/ibcs2_util.c b/sys/i386/ibcs2/ibcs2_util.c index f664e26..298fb84 100644 --- a/sys/i386/ibcs2/ibcs2_util.c +++ b/sys/i386/ibcs2/ibcs2_util.c @@ -34,9 +34,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> -#include <sys/namei.h> -#include <sys/malloc.h> -#include <sys/vnode.h> +#include <sys/syscallsubr.h> #include <i386/ibcs2/ibcs2_util.h> @@ -52,130 +50,10 @@ const char ibcs2_emul_path[] = "/compat/ibcs2"; * be in exists. */ int -ibcs2_emul_find(td, sgp, prefix, path, pbuf, cflag) - struct thread *td; - caddr_t *sgp; /* Pointer to stackgap memory */ - const char *prefix; - char *path; - char **pbuf; - int cflag; +ibcs2_emul_find(struct thread *td, char *path, enum uio_seg pathseg, + char **pbuf, int cflag) { - struct nameidata nd; - struct nameidata ndroot; - struct vattr vat; - struct vattr vatroot; - int error; - char *ptr, *buf, *cp; - size_t sz, len; - buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - *pbuf = path; - - for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) - continue; - - sz = MAXPATHLEN - (ptr - buf); - - /* - * If sgp is not given then the path is already in kernel space - */ - if (sgp == NULL) - error = copystr(path, ptr, sz, &len); - else - error = copyinstr(path, ptr, sz, &len); - - if (error) { - free(buf, M_TEMP); - return error; - } - - if (*ptr != '/') { - free(buf, M_TEMP); - return EINVAL; - } - - /* - * We know that there is a / somewhere in this pathname. - * Search backwards for it, to find the file's parent dir - * to see if it exists in the alternate tree. If it does, - * and we want to create a file (cflag is set). We don't - * need to worry about the root comparison in this case. - */ - - if (cflag) { - for (cp = &ptr[len] - 1; *cp != '/'; cp--); - *cp = '\0'; - - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); - - if ((error = namei(&nd)) != 0) { - free(buf, M_TEMP); - return error; - } - - *cp = '/'; - } - else { - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); - - if ((error = namei(&nd)) != 0) { - free(buf, M_TEMP); - return error; - } - - /* - * We now compare the vnode of the ibcs2_root to the one - * vnode asked. If they resolve to be the same, then we - * ignore the match so that the real root gets used. - * This avoids the problem of traversing "../.." to find the - * root directory and never finding it, because "/" resolves - * to the emulation root directory. This is expensive :-( - */ - NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, ibcs2_emul_path, - td); - - if ((error = namei(&ndroot)) != 0) { - /* Cannot happen! */ - free(buf, M_TEMP); - NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(nd.ni_vp); - return error; - } - - if ((error = VOP_GETATTR(nd.ni_vp, &vat, td->td_ucred, td)) != 0) { - goto done; - } - - if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, td->td_ucred, td)) - != 0) { - goto done; - } - - if (vat.va_fsid == vatroot.va_fsid && - vat.va_fileid == vatroot.va_fileid) { - error = ENOENT; - goto done; - } - - } - if (sgp == NULL) - *pbuf = buf; - else { - sz = &ptr[len] - buf; - if ((*pbuf = stackgap_alloc(sgp, sz + 1)) != NULL) - error = copyout(buf, *pbuf, sz); - else - error = ENAMETOOLONG; - free(buf, M_TEMP); - } - - -done: - NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(nd.ni_vp); - if (!cflag) { - NDFREE(&ndroot, NDF_ONLY_PNBUF); - vrele(ndroot.ni_vp); - } - return error; + return (kern_alternate_path(td, ibcs2_emul_path, path, pathseg, pbuf, + cflag)); } diff --git a/sys/i386/ibcs2/ibcs2_util.h b/sys/i386/ibcs2/ibcs2_util.h index 8c6ae3d..bf2513e 100644 --- a/sys/i386/ibcs2/ibcs2_util.h +++ b/sys/i386/ibcs2/ibcs2_util.h @@ -50,6 +50,7 @@ #include <sys/exec.h> #include <sys/sysent.h> #include <sys/proc.h> +#include <sys/uio.h> static __inline caddr_t stackgap_init(void); static __inline void *stackgap_alloc(caddr_t *, size_t); @@ -82,17 +83,22 @@ stackgap_alloc(sgp, sz) extern const char ibcs2_emul_path[]; -int ibcs2_emul_find(struct thread *, caddr_t *, const char *, char *, - char **, int); +int ibcs2_emul_find(struct thread *, char *, enum uio_seg, char **, int); -#define CHECKALTEXIST(p, sgp, path) \ - ibcs2_emul_find(td, sgp, ibcs2_emul_path, path, &(path), 0) +#define CHECKALT(td, upath, pathp, i) \ + do { \ + int _error; \ + \ + _error = ibcs2_emul_find(td, upath, UIO_USERSPACE, pathp, i); \ + if (*(pathp) == NULL) \ + return (_error); \ + } while (0) -#define CHECKALTCREAT(p, sgp, path) \ - ibcs2_emul_find(td, sgp, ibcs2_emul_path, path, &(path), 1) +#define CHECKALTEXIST(td, upath, pathp) CHECKALT(td, upath, pathp, 0) +#define CHECKALTCREAT(td, upath, pathp) CHECKALT(td, upath, pathp, 1) #ifdef SPX_HACK -int spx_open(struct thread *td, void *uap); +int spx_open(struct thread *td); #endif #endif /* !_IBCS2_UTIL_H_ */ diff --git a/sys/i386/ibcs2/ibcs2_xenix.c b/sys/i386/ibcs2/ibcs2_xenix.c index 5968443..0339f9f 100644 --- a/sys/i386/ibcs2/ibcs2_xenix.c +++ b/sys/i386/ibcs2/ibcs2_xenix.c @@ -37,9 +37,12 @@ __FBSDID("$FreeBSD$"); #include <sys/sysproto.h> #include <sys/jail.h> #include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/filio.h> #include <sys/vnode.h> +#include <sys/syscallsubr.h> #include <sys/sysctl.h> +#include <sys/unistd.h> #include <machine/cpu.h> @@ -195,33 +198,19 @@ xenix_scoinfo(struct thread *td, struct xenix_scoinfo_args *uap) int xenix_eaccess(struct thread *td, struct xenix_eaccess_args *uap) { - struct ucred *cred = td->td_ucred; - struct vnode *vp; - struct nameidata nd; - int error, flags; - caddr_t sg = stackgap_init(); - - CHECKALTEXIST(td, &sg, uap->path); - - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, - uap->path, td); - if ((error = namei(&nd)) != 0) - return error; - vp = nd.ni_vp; - - /* Flags == 0 means only check for existence. */ - if (uap->flags) { - flags = 0; - if (uap->flags & IBCS2_R_OK) - flags |= VREAD; - if (uap->flags & IBCS2_W_OK) - flags |= VWRITE; - if (uap->flags & IBCS2_X_OK) - flags |= VEXEC; - if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) - error = VOP_ACCESS(vp, flags, cred, td); - } - NDFREE(&nd, NDF_ONLY_PNBUF); - vput(vp); - return error; + char *path; + int error, bsd_flags; + + bsd_flags = 0; + if (uap->flags & IBCS2_R_OK) + bsd_flags |= R_OK; + if (uap->flags & IBCS2_W_OK) + bsd_flags |= W_OK; + if (uap->flags & IBCS2_X_OK) + bsd_flags |= X_OK; + + CHECKALTEXIST(td, uap->path, &path); + error = kern_access(td, path, UIO_SYSSPACE, bsd_flags); + free(path, M_TEMP); + return (error); } |