Index: sys/compat/linux/linux_file.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_file.c,v retrieving revision 1.69 diff -u -r1.69 linux_file.c --- sys/compat/linux/linux_file.c 17 Aug 2002 02:36:14 -0000 1.69 +++ sys/compat/linux/linux_file.c 1 Sep 2002 16:44:20 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -60,82 +61,68 @@ int linux_creat(struct thread *td, struct linux_creat_args *args) { - struct open_args /* { - char *path; - int flags; - int mode; - } */ bsd_open_args; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTCREAT(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(creat)) - printf(ARGS(creat, "%s, %d"), args->path, args->mode); + printf(ARGS(creat, "%s, %d"), path, args->mode); #endif - bsd_open_args.path = args->path; - bsd_open_args.mode = args->mode; - bsd_open_args.flags = O_WRONLY | O_CREAT | O_TRUNC; - return open(td, &bsd_open_args); + error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC, + args->mode); + LFREEPATH(path); + return (error); } #endif /*!__alpha__*/ int linux_open(struct thread *td, struct linux_open_args *args) { - struct open_args /* { - char *path; - int flags; - int mode; - } */ bsd_open_args; struct proc *p = td->td_proc; - int error; - caddr_t sg; + char *path; + int bsd_flags, error; - sg = stackgap_init(); - if (args->flags & LINUX_O_CREAT) - CHECKALTCREAT(td, &sg, args->path); + LCONVPATHCREAT(td, args->path, &path); else - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(open)) printf(ARGS(open, "%s, 0x%x, 0x%x"), - args->path, args->flags, args->mode); + path, args->flags, args->mode); #endif - bsd_open_args.flags = 0; + bsd_flags = 0; if (args->flags & LINUX_O_RDONLY) - bsd_open_args.flags |= O_RDONLY; + bsd_flags |= O_RDONLY; if (args->flags & LINUX_O_WRONLY) - bsd_open_args.flags |= O_WRONLY; + bsd_flags |= O_WRONLY; if (args->flags & LINUX_O_RDWR) - bsd_open_args.flags |= O_RDWR; + bsd_flags |= O_RDWR; if (args->flags & LINUX_O_NDELAY) - bsd_open_args.flags |= O_NONBLOCK; + bsd_flags |= O_NONBLOCK; if (args->flags & LINUX_O_APPEND) - bsd_open_args.flags |= O_APPEND; + bsd_flags |= O_APPEND; if (args->flags & LINUX_O_SYNC) - bsd_open_args.flags |= O_FSYNC; + bsd_flags |= O_FSYNC; if (args->flags & LINUX_O_NONBLOCK) - bsd_open_args.flags |= O_NONBLOCK; + bsd_flags |= O_NONBLOCK; if (args->flags & LINUX_FASYNC) - bsd_open_args.flags |= O_ASYNC; + bsd_flags |= O_ASYNC; if (args->flags & LINUX_O_CREAT) - bsd_open_args.flags |= O_CREAT; + bsd_flags |= O_CREAT; if (args->flags & LINUX_O_TRUNC) - bsd_open_args.flags |= O_TRUNC; + bsd_flags |= O_TRUNC; if (args->flags & LINUX_O_EXCL) - bsd_open_args.flags |= O_EXCL; + bsd_flags |= O_EXCL; if (args->flags & LINUX_O_NOCTTY) - bsd_open_args.flags |= O_NOCTTY; - bsd_open_args.path = args->path; - bsd_open_args.mode = args->mode; + bsd_flags |= O_NOCTTY; - error = open(td, &bsd_open_args); + error = kern_open(td, path, UIO_SYSSPACE, bsd_flags, args->mode); PROC_LOCK(p); - if (!error && !(bsd_open_args.flags & O_NOCTTY) && + if (!error && !(bsd_flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { struct file *fp; @@ -154,6 +141,7 @@ printf(LMSG("open returns error %d"), error); #endif } + LFREEPATH(path); return error; } @@ -493,214 +481,213 @@ int linux_access(struct thread *td, struct linux_access_args *args) { - struct access_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(access)) - printf(ARGS(access, "%s, %d"), args->path, args->flags); + printf(ARGS(access, "%s, %d"), path, args->flags); #endif - bsd.path = args->path; - bsd.flags = args->flags; - - return access(td, &bsd); + error = kern_access(td, path, UIO_SYSSPACE, args->flags); + LFREEPATH(path); + return (error); } int linux_unlink(struct thread *td, struct linux_unlink_args *args) { - struct unlink_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(unlink)) - printf(ARGS(unlink, "%s"), args->path); + printf(ARGS(unlink, "%s"), path); #endif - bsd.path = args->path; - return unlink(td, &bsd); + error = kern_unlink(td, path, UIO_SYSSPACE); + LFREEPATH(path); + return (error); } int linux_chdir(struct thread *td, struct linux_chdir_args *args) { - struct chdir_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(chdir)) - printf(ARGS(chdir, "%s"), args->path); + printf(ARGS(chdir, "%s"), path); #endif - bsd.path = args->path; - - return chdir(td, &bsd); + error = kern_chdir(td, path, UIO_SYSSPACE); + LFREEPATH(path); + return (error); } int linux_chmod(struct thread *td, struct linux_chmod_args *args) { - struct chmod_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(chmod)) - printf(ARGS(chmod, "%s, %d"), args->path, args->mode); + printf(ARGS(chmod, "%s, %d"), path, args->mode); #endif - bsd.path = args->path; - bsd.mode = args->mode; - - return chmod(td, &bsd); + error = kern_chmod(td, path, UIO_SYSSPACE, args->mode); + LFREEPATH(path); + return (error); } int linux_mkdir(struct thread *td, struct linux_mkdir_args *args) { - struct mkdir_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTCREAT(td, &sg, args->path); + LCONVPATHCREAT(td, args->path, &path); #ifdef DEBUG if (ldebug(mkdir)) - printf(ARGS(mkdir, "%s, %d"), args->path, args->mode); + printf(ARGS(mkdir, "%s, %d"), path, args->mode); #endif - bsd.path = args->path; - bsd.mode = args->mode; - - return mkdir(td, &bsd); + error = kern_mkdir(td, path, UIO_SYSSPACE, args->mode); + LFREEPATH(path); + return (error); } int linux_rmdir(struct thread *td, struct linux_rmdir_args *args) { - struct rmdir_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(rmdir)) - printf(ARGS(rmdir, "%s"), args->path); + printf(ARGS(rmdir, "%s"), path); #endif - bsd.path = args->path; - - return rmdir(td, &bsd); + error = kern_rmdir(td, path, UIO_SYSSPACE); + LFREEPATH(path); + return (error); } int linux_rename(struct thread *td, struct linux_rename_args *args) { - struct rename_args bsd; - caddr_t sg; + char *from, *to; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->from); - CHECKALTCREAT(td, &sg, args->to); + 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); + if (to == NULL) { + LFREEPATH(from); + return (error); + } #ifdef DEBUG if (ldebug(rename)) - printf(ARGS(rename, "%s, %s"), args->from, args->to); + printf(ARGS(rename, "%s, %s"), from, to); #endif - bsd.from = args->from; - bsd.to = args->to; - - return rename(td, &bsd); + error = kern_rename(td, from, to, UIO_SYSSPACE); + LFREEPATH(from); + LFREEPATH(to); + return (error); } int linux_symlink(struct thread *td, struct linux_symlink_args *args) { - struct symlink_args bsd; - caddr_t sg; + char *path, *to; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); - CHECKALTCREAT(td, &sg, args->to); + 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); + if (to == NULL) { + LFREEPATH(path); + return (error); + } #ifdef DEBUG if (ldebug(symlink)) - printf(ARGS(symlink, "%s, %s"), args->path, args->to); + printf(ARGS(symlink, "%s, %s"), path, to); #endif - bsd.path = args->path; - bsd.link = args->to; - - return symlink(td, &bsd); + error = kern_symlink(td, path, to, UIO_SYSSPACE); + LFREEPATH(path); + LFREEPATH(to); + return (error); } int linux_readlink(struct thread *td, struct linux_readlink_args *args) { - struct readlink_args bsd; - caddr_t sg; + char *name; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->name); + LCONVPATHEXIST(td, args->name, &name); #ifdef DEBUG if (ldebug(readlink)) - printf(ARGS(readlink, "%s, %p, %d"), - args->name, (void *)args->buf, args->count); + printf(ARGS(readlink, "%s, %p, %d"), name, (void *)args->buf, + args->count); #endif - bsd.path = args->name; - bsd.buf = args->buf; - bsd.count = args->count; - - return readlink(td, &bsd); + error = kern_readlink(td, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE, + args->count); + LFREEPATH(name); + return (error); } int linux_truncate(struct thread *td, struct linux_truncate_args *args) { - struct truncate_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(truncate)) - printf(ARGS(truncate, "%s, %ld"), args->path, - (long)args->length); + printf(ARGS(truncate, "%s, %ld"), path, (long)args->length); #endif - bsd.path = args->path; - bsd.length = args->length; - return truncate(td, &bsd); + error = kern_truncate(td, path, UIO_SYSSPACE, args->length); + LFREEPATH(path); + return (error); } int linux_link(struct thread *td, struct linux_link_args *args) { - struct link_args bsd; - caddr_t sg; + char *path, *to; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); - CHECKALTCREAT(td, &sg, args->to); + 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); + if (to == NULL) { + LFREEPATH(path); + return (error); + } #ifdef DEBUG if (ldebug(link)) - printf(ARGS(link, "%s, %s"), args->path, args->to); + printf(ARGS(link, "%s, %s"), path, to); #endif - - bsd.path = args->path; - bsd.link = args->to; - - return link(td, &bsd); + error = kern_link(td, path, to, UIO_SYSSPACE); + LFREEPATH(path); + LFREEPATH(to); + return (error); } #ifndef __alpha__ @@ -944,30 +931,22 @@ static int fcntl_common(struct thread *td, struct linux_fcntl64_args *args) { - struct fcntl_args fcntl_args; struct file *fp; + long arg; int error, result; - fcntl_args.fd = args->fd; - switch (args->cmd) { case LINUX_F_DUPFD: - fcntl_args.cmd = F_DUPFD; - fcntl_args.arg = args->arg; - return (fcntl(td, &fcntl_args)); + return (kern_fcntl(td, args->fd, F_DUPFD, args->arg)); case LINUX_F_GETFD: - fcntl_args.cmd = F_GETFD; - return (fcntl(td, &fcntl_args)); + return (kern_fcntl(td, args->fd, F_GETFD, 0)); case LINUX_F_SETFD: - fcntl_args.cmd = F_SETFD; - fcntl_args.arg = args->arg; - return (fcntl(td, &fcntl_args)); + return (kern_fcntl(td, args->fd, F_SETFD, args->arg)); case LINUX_F_GETFL: - fcntl_args.cmd = F_GETFL; - error = fcntl(td, &fcntl_args); + error = kern_fcntl(td, args->fd, F_GETFL, 0); result = td->td_retval[0]; td->td_retval[0] = 0; if (result & O_RDONLY) @@ -987,21 +966,19 @@ return (error); case LINUX_F_SETFL: - fcntl_args.arg = 0; + arg = 0; if (args->arg & LINUX_O_NDELAY) - fcntl_args.arg |= O_NONBLOCK; + arg |= O_NONBLOCK; if (args->arg & LINUX_O_APPEND) - fcntl_args.arg |= O_APPEND; + arg |= O_APPEND; if (args->arg & LINUX_O_SYNC) - fcntl_args.arg |= O_FSYNC; + arg |= O_FSYNC; if (args->arg & LINUX_FASYNC) - fcntl_args.arg |= O_ASYNC; - fcntl_args.cmd = F_SETFL; - return (fcntl(td, &fcntl_args)); + arg |= O_ASYNC; + return (kern_fcntl(td, args->fd, F_SETFL, arg)); case LINUX_F_GETOWN: - fcntl_args.cmd = F_GETOWN; - return (fcntl(td, &fcntl_args)); + return (kern_fcntl(td, args->fd, F_GETOWN, 0)); case LINUX_F_SETOWN: /* @@ -1018,9 +995,7 @@ } fdrop(fp, td); - fcntl_args.cmd = F_SETOWN; - fcntl_args.arg = args->arg; - return (fcntl(td, &fcntl_args)); + return (kern_fcntl(td, args->fd, F_SETOWN, args->arg)); } return (EINVAL); @@ -1030,14 +1005,9 @@ linux_fcntl(struct thread *td, struct linux_fcntl_args *args) { struct linux_fcntl64_args args64; - struct fcntl_args fcntl_args; struct l_flock linux_flock; - struct flock *bsd_flock; + struct flock bsd_flock; int error; - caddr_t sg; - - sg = stackgap_init(); - bsd_flock = (struct flock *)stackgap_alloc(&sg, sizeof(bsd_flock)); #ifdef DEBUG if (ldebug(fcntl)) @@ -1050,14 +1020,11 @@ sizeof(linux_flock)); if (error) return (error); - linux_to_bsd_flock(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_GETLK; - fcntl_args.arg = (long)bsd_flock; - error = fcntl(td, &fcntl_args); + 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); + bsd_to_linux_flock(&bsd_flock, &linux_flock); return (copyout(&linux_flock, (caddr_t)args->arg, sizeof(linux_flock))); @@ -1066,22 +1033,18 @@ sizeof(linux_flock)); if (error) return (error); - linux_to_bsd_flock(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_SETLK; - fcntl_args.arg = (long)bsd_flock; - return (fcntl(td, &fcntl_args)); + 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((caddr_t)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); - linux_to_bsd_flock(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_SETLKW; - fcntl_args.arg = (long)bsd_flock; - return (fcntl(td, &fcntl_args)); + linux_to_bsd_flock(&linux_flock, &bsd_flock); + return (kern_fcntl(td, args->fd, F_SETLKW, + (intptr_t)&bsd_flock)); } args64.fd = args->fd; @@ -1094,14 +1057,9 @@ int linux_fcntl64(struct thread *td, struct linux_fcntl64_args *args) { - struct fcntl_args fcntl_args; struct l_flock64 linux_flock; - struct flock *bsd_flock; + struct flock bsd_flock; int error; - caddr_t sg; - - sg = stackgap_init(); - bsd_flock = (struct flock *)stackgap_alloc(&sg, sizeof(bsd_flock)); #ifdef DEBUG if (ldebug(fcntl64)) @@ -1115,14 +1073,11 @@ sizeof(linux_flock)); if (error) return (error); - linux_to_bsd_flock64(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_GETLK; - fcntl_args.arg = (long)bsd_flock; - error = fcntl(td, &fcntl_args); + 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); + bsd_to_linux_flock64(&bsd_flock, &linux_flock); return (copyout(&linux_flock, (caddr_t)args->arg, sizeof(linux_flock))); @@ -1132,11 +1087,9 @@ sizeof(linux_flock)); if (error) return (error); - linux_to_bsd_flock64(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_SETLK; - fcntl_args.arg = (long)bsd_flock; - return (fcntl(td, &fcntl_args)); + linux_to_bsd_flock64(&linux_flock, &bsd_flock); + return (kern_fcntl(td, args->fd, F_SETLK, + (intptr_t)&bsd_flock)); case LINUX_F_SETLKW: case LINUX_F_SETLKW64: @@ -1144,11 +1097,9 @@ sizeof(linux_flock)); if (error) return (error); - linux_to_bsd_flock64(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_SETLKW; - fcntl_args.arg = (long)bsd_flock; - return (fcntl(td, &fcntl_args)); + 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)); @@ -1158,41 +1109,33 @@ int linux_chown(struct thread *td, struct linux_chown_args *args) { - struct chown_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(chown)) - printf(ARGS(chown, "%s, %d, %d"), args->path, args->uid, - args->gid); + printf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid); #endif - - bsd.path = args->path; - bsd.uid = args->uid; - bsd.gid = args->gid; - return (chown(td, &bsd)); + error = kern_chown(td, path, UIO_SYSSPACE, args->uid, args->gid); + LFREEPATH(path); + return (error); } int linux_lchown(struct thread *td, struct linux_lchown_args *args) { - struct lchown_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(lchown)) - printf(ARGS(lchown, "%s, %d, %d"), args->path, args->uid, - args->gid); + printf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid); #endif - - bsd.path = args->path; - bsd.uid = args->uid; - bsd.gid = args->gid; - return (lchown(td, &bsd)); + error = kern_lchown(td, path, UIO_SYSSPACE, args->uid, args->gid); + LFREEPATH(path); + return (error); } Index: sys/compat/linux/linux_getcwd.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_getcwd.c,v retrieving revision 1.7 diff -u -r1.7 linux_getcwd.c --- sys/compat/linux/linux_getcwd.c 4 Aug 2002 10:29:24 -0000 1.7 +++ sys/compat/linux/linux_getcwd.c 1 Sep 2002 16:44:20 -0000 @@ -42,12 +42,12 @@ #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -414,8 +414,7 @@ int linux_getcwd(struct thread *td, struct linux_getcwd_args *args) { - struct __getcwd_args bsd; - caddr_t sg, bp, bend, path; + caddr_t bp, bend, path; int error, len, lenused; #ifdef DEBUG @@ -423,28 +422,25 @@ args->buf, (long)args->bufsize); #endif - sg = stackgap_init(); - bsd.buf = stackgap_alloc(&sg, SPARE_USRSPACE); - bsd.buflen = SPARE_USRSPACE; - error = __getcwd(td, &bsd); + len = args->bufsize; + + if (len > MAXPATHLEN*4) + len = MAXPATHLEN*4; + else if (len < 2) + return ERANGE; + + path = (char *)malloc(len, M_TEMP, M_WAITOK); + + error = kern___getcwd(td, path, UIO_SYSSPACE, len); if (!error) { - lenused = strlen(bsd.buf) + 1; + lenused = strlen(path) + 1; if (lenused <= args->bufsize) { td->td_retval[0] = lenused; - error = copyout(bsd.buf, args->buf, lenused); + error = copyout(path, args->buf, lenused); } else error = ERANGE; } else { - len = args->bufsize; - - if (len > MAXPATHLEN*4) - len = MAXPATHLEN*4; - else if (len < 2) - return ERANGE; - - path = (char *)malloc(len, M_TEMP, M_WAITOK); - bp = &path[len]; bend = bp; *(--bp) = '\0'; @@ -464,10 +460,9 @@ td->td_retval[0] = lenused; /* put the result into user buffer */ error = copyout(bp, args->buf, lenused); - -out: - free(path, M_TEMP); } +out: + free(path, M_TEMP); return (error); } Index: sys/compat/linux/linux_ipc.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_ipc.c,v retrieving revision 1.30 diff -u -r1.30 linux_ipc.c --- sys/compat/linux/linux_ipc.c 2 Jun 2002 20:05:42 -0000 1.30 +++ sys/compat/linux/linux_ipc.c 1 Sep 2002 16:44:20 -0000 @@ -233,76 +233,69 @@ linux_semctl(struct thread *td, struct linux_semctl_args *args) { struct l_semid_ds linux_semid; - struct __semctl_args /* { - int semid; - int semnum; - int cmd; - union semun *arg; - } */ bsd_args; struct l_seminfo linux_seminfo; - int error; - union semun *unptr; - caddr_t sg; - - sg = stackgap_init(); + struct semid_ds dsbuf; + union semun user_arg, sys_arg; + int cmd, error; - /* Make sure the arg parameter can be copied in. */ - unptr = stackgap_alloc(&sg, sizeof(union semun)); - bcopy(&args->arg, unptr, sizeof(union semun)); - - bsd_args.semid = args->semid; - bsd_args.semnum = args->semnum; - bsd_args.arg = unptr; + switch (args->cmd) { + case LINUX_IPC_SET: + case LINUX_IPC_STAT: + case LINUX_SEM_STAT: + case LINUX_IPC_INFO: + case LINUX_SEM_INFO: + case LINUX_SETVAL: + case LINUX_GETALL: + case LINUX_SETALL: + error = copyin(&args->arg, &user_arg, sizeof(union semun)); + if (error) + return (error); + break; + } switch (args->cmd) { case LINUX_IPC_RMID: - bsd_args.cmd = IPC_RMID; + cmd = IPC_RMID; break; case LINUX_GETNCNT: - bsd_args.cmd = GETNCNT; + cmd = GETNCNT; break; case LINUX_GETPID: - bsd_args.cmd = GETPID; + cmd = GETPID; break; case LINUX_GETVAL: - bsd_args.cmd = GETVAL; + cmd = GETVAL; break; case LINUX_GETZCNT: - bsd_args.cmd = GETZCNT; + cmd = GETZCNT; break; case LINUX_SETVAL: - bsd_args.cmd = SETVAL; + cmd = SETVAL; break; case LINUX_IPC_SET: - bsd_args.cmd = IPC_SET; - error = copyin((caddr_t)args->arg.buf, &linux_semid, - sizeof(linux_semid)); + error = copyin(user_arg.buf, &linux_semid, sizeof(linux_semid)); if (error) return (error); - unptr->buf = stackgap_alloc(&sg, sizeof(struct semid_ds)); - linux_to_bsd_semid_ds(&linux_semid, unptr->buf); - return __semctl(td, &bsd_args); + linux_to_bsd_semid_ds(&linux_semid, &dsbuf); + sys_arg.buf = &dsbuf; + return (kern_semctl(td, args->semid, args->semnum, IPC_SET, + &sys_arg)); case LINUX_IPC_STAT: case LINUX_SEM_STAT: - if( args->cmd == LINUX_IPC_STAT ) - bsd_args.cmd = IPC_STAT; + if (args->cmd == LINUX_IPC_STAT) + cmd = IPC_STAT; else - bsd_args.cmd = SEM_STAT; - unptr->buf = stackgap_alloc(&sg, sizeof(struct semid_ds)); - error = __semctl(td, &bsd_args); + cmd = SEM_STAT; + sys_arg.buf = &dsbuf; + error = kern_semctl(td, args->semid, args->semnum, cmd, + &sys_arg); if (error) return error; - td->td_retval[0] = IXSEQ_TO_IPCID(bsd_args.semid, - unptr->buf->sem_perm); - bsd_to_linux_semid_ds(unptr->buf, &linux_semid); - return copyout(&linux_semid, (caddr_t)args->arg.buf, - sizeof(linux_semid)); + td->td_retval[0] = IXSEQ_TO_IPCID(args->semid, dsbuf.sem_perm); + bsd_to_linux_semid_ds(&dsbuf, &linux_semid); + return copyout(&linux_semid, user_arg.buf, sizeof(linux_semid)); case LINUX_IPC_INFO: case LINUX_SEM_INFO: - error = copyin((caddr_t)args->arg.buf, &linux_seminfo, - sizeof(linux_seminfo) ); - if (error) - return error; bcopy(&seminfo, &linux_seminfo, sizeof(linux_seminfo) ); /* XXX BSD equivalent? #define used_semids 10 @@ -310,12 +303,12 @@ linux_seminfo.semusz = used_semids; linux_seminfo.semaem = used_sems; */ - error = copyout((caddr_t)&linux_seminfo, (caddr_t)args->arg.buf, - sizeof(linux_seminfo) ); + error = copyout(&linux_seminfo, user_arg.buf, + sizeof(linux_seminfo)); if (error) return error; td->td_retval[0] = seminfo.semmni; - return 0; /* No need for __semctl call */ + return 0; case LINUX_GETALL: /* FALLTHROUGH */ case LINUX_SETALL: @@ -324,7 +317,7 @@ uprintf("linux: 'ipc' typ=%d not implemented\n", args->cmd); return EINVAL; } - return __semctl(td, &bsd_args); + return (kern_semctl(td, args->semid, args->semnum, cmd, &user_arg)); } int @@ -445,84 +438,51 @@ int linux_shmctl(struct thread *td, struct linux_shmctl_args *args) { - struct l_shmid_ds linux_shmid; + struct l_shmid_ds linux_shmid; struct l_shminfo linux_shminfo; struct l_shm_info linux_shm_info; - struct shmctl_args /* { - int shmid; - int cmd; - struct shmid_ds *buf; - } */ bsd_args; - int error; - caddr_t sg = stackgap_init(); - - switch (args->cmd) { + struct shminfo shminfo; + struct shm_info shm_info; + struct shmid_ds shmid_ds; + int error; + switch (args->cmd) { case LINUX_IPC_INFO: - bsd_args.shmid = args->shmid; - bsd_args.cmd = IPC_INFO; - bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shminfo)); - if ((error = shmctl(td, &bsd_args))) - return error; - bsd_to_linux_shminfo( (struct shminfo *)bsd_args.buf, &linux_shminfo ); - return copyout(&linux_shminfo, (caddr_t)args->buf, sizeof(shminfo)); - + error = kern_shmctl(td, args->shmid, IPC_INFO, + (struct shmid_ds *)&shminfo); + if (error) + return (error); + bsd_to_linux_shminfo(&shminfo, &linux_shminfo); + return copyout(&linux_shminfo, args->buf, sizeof(shminfo)); case LINUX_SHM_INFO: - bsd_args.shmid = args->shmid; - bsd_args.cmd = SHM_INFO; - bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shm_info)); - if ((error = shmctl(td, &bsd_args))) - return error; - bsd_to_linux_shm_info( (struct shm_info *)bsd_args.buf, &linux_shm_info ); - return copyout(&linux_shm_info, (caddr_t)args->buf, sizeof(struct shm_info)); - - case LINUX_IPC_STAT: - bsd_args.shmid = args->shmid; - bsd_args.cmd = IPC_STAT; - bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds)); - if ((error = shmctl(td, &bsd_args))) - return error; - bsd_to_linux_shmid_ds(bsd_args.buf, &linux_shmid); - return copyout(&linux_shmid, (caddr_t)args->buf, sizeof(linux_shmid)); - + error = kern_shmctl(td, args->shmid, SHM_INFO, + (struct shmid_ds *)&shm_info); + if (error) + return (error); + bsd_to_linux_shm_info(&shm_info, &linux_shm_info); + return copyout(&linux_shm_info, args->buf, sizeof(shm_info)); + case LINUX_IPC_STAT: case LINUX_SHM_STAT: - bsd_args.shmid = args->shmid; - bsd_args.cmd = SHM_STAT; - bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds)); - if ((error = shmctl(td, &bsd_args))) { - return error; - } - bsd_to_linux_shmid_ds(bsd_args.buf, &linux_shmid); - return copyout(&linux_shmid, (caddr_t)args->buf, sizeof(linux_shmid)); + error = kern_shmctl(td, args->shmid, + (args->cmd == LINUX_IPC_STAT) ? IPC_STAT : SHM_STAT, + &shmid_ds); + if (error) + return (error); + bsd_to_linux_shmid_ds(&shmid_ds, &linux_shmid); + return copyout(&linux_shmid, args->buf, sizeof(linux_shmid)); + case LINUX_IPC_SET: + error = copyin(args->buf, &linux_shmid, sizeof(linux_shmid)); + if (error) + return error; + linux_to_bsd_shmid_ds(&linux_shmid, &shmid_ds); + return (kern_shmctl(td, args->shmid, IPC_SET, &shmid_ds)); + case LINUX_IPC_RMID: + return (kern_shmctl(td, args->shmid, IPC_RMID, NULL)); - case LINUX_IPC_SET: - if ((error = copyin((caddr_t)args->buf, &linux_shmid, - sizeof(linux_shmid)))) - return error; - bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds)); - linux_to_bsd_shmid_ds(&linux_shmid, bsd_args.buf); - bsd_args.shmid = args->shmid; - bsd_args.cmd = IPC_SET; - return shmctl(td, &bsd_args); - - case LINUX_IPC_RMID: - bsd_args.shmid = args->shmid; - bsd_args.cmd = IPC_RMID; - if (args->buf == NULL) - bsd_args.buf = NULL; - else { - if ((error = copyin((caddr_t)args->buf, &linux_shmid, - sizeof(linux_shmid)))) - return error; - bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds)); - linux_to_bsd_shmid_ds(&linux_shmid, bsd_args.buf); + case LINUX_SHM_LOCK: + case LINUX_SHM_UNLOCK: + default: + uprintf("linux: 'ipc' typ=%d not implemented\n", args->cmd); + return EINVAL; } - return shmctl(td, &bsd_args); - - case LINUX_SHM_LOCK: - case LINUX_SHM_UNLOCK: - default: - uprintf("linux: 'ipc' typ=%d not implemented\n", args->cmd); - return EINVAL; - } } Index: sys/compat/linux/linux_misc.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.125 diff -u -r1.125 linux_misc.c --- sys/compat/linux/linux_misc.c 4 Aug 2002 10:29:24 -0000 1.125 +++ sys/compat/linux/linux_misc.c 1 Sep 2002 16:44:20 -0000 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -235,16 +236,15 @@ unsigned long file_offset; vm_offset_t buffer; unsigned long bss_size; + char *library; int error; - caddr_t sg; int locked; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->library); + LCONVPATHEXIST(td, args->library, &library); #ifdef DEBUG if (ldebug(uselib)) - printf(ARGS(uselib, "%s"), args->library); + printf(ARGS(uselib, "%s"), library); #endif a_out = NULL; @@ -255,8 +255,9 @@ * XXX: This code should make use of vn_open(), rather than doing * all this stuff itself. */ - NDINIT(&ni, LOOKUP, FOLLOW|LOCKLEAF, UIO_USERSPACE, args->library, td); + NDINIT(&ni, LOOKUP, FOLLOW|LOCKLEAF, UIO_SYSSPACE, library, td); error = namei(&ni); + LFREEPATH(library); if (error) goto cleanup; @@ -476,9 +477,7 @@ int linux_select(struct thread *td, struct linux_select_args *args) { - struct select_args bsa; struct timeval tv0, tv1, utv, *tvp; - caddr_t sg; int error; #ifdef DEBUG @@ -488,13 +487,6 @@ (void *)args->exceptfds, (void *)args->timeout); #endif - error = 0; - bsa.nd = args->nfds; - bsa.in = args->readfds; - bsa.ou = args->writefds; - bsa.ex = args->exceptfds; - bsa.tv = (struct timeval *)args->timeout; - /* * Store current time for computation of the amount of * time left. @@ -514,8 +506,6 @@ * The timeval was invalid. Convert it to something * valid that will act as it does under Linux. */ - sg = stackgap_init(); - tvp = stackgap_alloc(&sg, sizeof(utv)); utv.tv_sec += utv.tv_usec / 1000000; utv.tv_usec %= 1000000; if (utv.tv_usec < 0) { @@ -524,14 +514,15 @@ } if (utv.tv_sec < 0) timevalclear(&utv); - if ((error = copyout(&utv, tvp, sizeof(utv)))) - goto select_out; - bsa.tv = tvp; } microtime(&tv0); - } + tvp = &utv; + } else + tvp = NULL; + + error = kern_select(td, args->nfds, args->readfds, args->writefds, + args->exceptfds, tvp); - error = select(td, &bsa); #ifdef DEBUG if (ldebug(select)) printf(LMSG("real select returns %d"), error); @@ -729,42 +720,34 @@ int linux_utime(struct thread *td, struct linux_utime_args *args) { - struct utimes_args /* { - char *path; - struct timeval *tptr; - } */ bsdutimes; struct timeval tv[2], *tvp; struct l_utimbuf lut; + char *fname; int error; - caddr_t sg; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->fname); + LCONVPATHEXIST(td, args->fname, &fname); #ifdef DEBUG if (ldebug(utime)) - printf(ARGS(utime, "%s, *"), args->fname); + printf(ARGS(utime, "%s, *"), fname); #endif if (args->times) { - if ((error = copyin((caddr_t)args->times, &lut, sizeof lut))) + if ((error = copyin((caddr_t)args->times, &lut, sizeof lut))) { + LFREEPATH(fname); return error; + } tv[0].tv_sec = lut.l_actime; tv[0].tv_usec = 0; tv[1].tv_sec = lut.l_modtime; tv[1].tv_usec = 0; - /* so that utimes can copyin */ - tvp = (struct timeval *)stackgap_alloc(&sg, sizeof(tv)); - if (tvp == NULL) - return (ENAMETOOLONG); - if ((error = copyout(tv, tvp, sizeof(tv)))) - return error; - bsdutimes.tptr = tvp; + tvp = tv; } else - bsdutimes.tptr = NULL; + tvp = NULL; - bsdutimes.path = args->fname; - return utimes(td, &bsdutimes); + error = kern_utimes(td, fname, UIO_SYSSPACE, tvp, UIO_SYSSPACE); + LFREEPATH(fname); + return (error); } #endif /* __i386__ */ @@ -868,30 +851,23 @@ int linux_mknod(struct thread *td, struct linux_mknod_args *args) { - caddr_t sg; - struct mknod_args bsd_mknod; - struct mkfifo_args bsd_mkfifo; - - sg = stackgap_init(); + char *path; + int error; - CHECKALTCREAT(td, &sg, args->path); + LCONVPATHCREAT(td, args->path, &path); #ifdef DEBUG if (ldebug(mknod)) - printf(ARGS(mknod, "%s, %d, %d"), - args->path, args->mode, args->dev); + printf(ARGS(mknod, "%s, %d, %d"), path, args->mode, args->dev); #endif - if (args->mode & S_IFIFO) { - bsd_mkfifo.path = args->path; - bsd_mkfifo.mode = args->mode; - return mkfifo(td, &bsd_mkfifo); - } else { - bsd_mknod.path = args->path; - bsd_mknod.mode = args->mode; - bsd_mknod.dev = args->dev; - return mknod(td, &bsd_mknod); - } + if (args->mode & S_IFIFO) + error = kern_mkfifo(td, path, UIO_SYSSPACE, args->mode); + else + error = kern_mknod(td, path, UIO_SYSSPACE, args->mode, + args->dev); + LFREEPATH(path); + return (error); } /* @@ -1071,10 +1047,10 @@ int linux_setrlimit(struct thread *td, struct linux_setrlimit_args *args) { - struct __setrlimit_args bsd; + struct rlimit bsd_rlim; struct l_rlimit rlim; + u_int which; int error; - caddr_t sg = stackgap_init(); #ifdef DEBUG if (ldebug(setrlimit)) @@ -1085,27 +1061,26 @@ if (args->resource >= LINUX_RLIM_NLIMITS) return (EINVAL); - bsd.which = linux_to_bsd_resource[args->resource]; - if (bsd.which == -1) + which = linux_to_bsd_resource[args->resource]; + if (which == -1) return (EINVAL); error = copyin((caddr_t)args->rlim, &rlim, sizeof(rlim)); if (error) return (error); - bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); - bsd.rlp->rlim_cur = (rlim_t)rlim.rlim_cur; - bsd.rlp->rlim_max = (rlim_t)rlim.rlim_max; - return (setrlimit(td, &bsd)); + bsd_rlim.rlim_cur = (rlim_t)rlim.rlim_cur; + bsd_rlim.rlim_max = (rlim_t)rlim.rlim_max; + return (dosetrlimit(td, which, &bsd_rlim)); } int linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args) { - struct __getrlimit_args bsd; struct l_rlimit rlim; - int error; - caddr_t sg = stackgap_init(); + struct proc *p = td->td_proc; + struct rlimit *bsd_rlp; + u_int which; #ifdef DEBUG if (ldebug(old_getrlimit)) @@ -1116,19 +1091,15 @@ if (args->resource >= LINUX_RLIM_NLIMITS) return (EINVAL); - bsd.which = linux_to_bsd_resource[args->resource]; - if (bsd.which == -1) + which = linux_to_bsd_resource[args->resource]; + if (which == -1) return (EINVAL); + bsd_rlp = &p->p_rlimit[which]; - bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); - error = getrlimit(td, &bsd); - if (error) - return (error); - - rlim.rlim_cur = (unsigned long)bsd.rlp->rlim_cur; + rlim.rlim_cur = (unsigned long)bsd_rlp->rlim_cur; if (rlim.rlim_cur == ULONG_MAX) rlim.rlim_cur = LONG_MAX; - rlim.rlim_max = (unsigned long)bsd.rlp->rlim_max; + rlim.rlim_max = (unsigned long)bsd_rlp->rlim_max; if (rlim.rlim_max == ULONG_MAX) rlim.rlim_max = LONG_MAX; return (copyout(&rlim, (caddr_t)args->rlim, sizeof(rlim))); @@ -1137,10 +1108,10 @@ int linux_getrlimit(struct thread *td, struct linux_getrlimit_args *args) { - struct __getrlimit_args bsd; struct l_rlimit rlim; - int error; - caddr_t sg = stackgap_init(); + struct proc *p = td->td_proc; + struct rlimit *bsd_rlp; + u_int which; #ifdef DEBUG if (ldebug(getrlimit)) @@ -1151,17 +1122,13 @@ if (args->resource >= LINUX_RLIM_NLIMITS) return (EINVAL); - bsd.which = linux_to_bsd_resource[args->resource]; - if (bsd.which == -1) + which = linux_to_bsd_resource[args->resource]; + if (which == -1) return (EINVAL); + bsd_rlp = &p->p_rlimit[which]; - bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); - error = getrlimit(td, &bsd); - if (error) - return (error); - - rlim.rlim_cur = (l_ulong)bsd.rlp->rlim_cur; - rlim.rlim_max = (l_ulong)bsd.rlp->rlim_max; + rlim.rlim_cur = (l_ulong)bsd_rlp->rlim_cur; + rlim.rlim_max = (l_ulong)bsd_rlp->rlim_max; return (copyout(&rlim, (caddr_t)args->rlim, sizeof(rlim))); } #endif /*!__alpha__*/ Index: sys/compat/linux/linux_signal.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_signal.c,v retrieving revision 1.34 diff -u -r1.34 linux_signal.c --- sys/compat/linux/linux_signal.c 2 Jun 2002 20:05:42 -0000 1.34 +++ sys/compat/linux/linux_signal.c 1 Sep 2002 16:44:20 -0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -134,36 +135,27 @@ linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, l_sigaction_t *linux_osa) { - struct sigaction *nsa, *osa; - struct sigaction_args sa_args; - int error; - caddr_t sg = stackgap_init(); + struct sigaction act, oact, *nsa, *osa; + int error, sig; if (linux_sig <= 0 || linux_sig > LINUX_NSIG) return (EINVAL); - if (linux_osa != NULL) - osa = stackgap_alloc(&sg, sizeof(struct sigaction)); - else - osa = NULL; - + osa = (linux_osa != NULL) ? &oact : NULL; if (linux_nsa != NULL) { - nsa = stackgap_alloc(&sg, sizeof(struct sigaction)); + nsa = &act; linux_to_bsd_sigaction(linux_nsa, nsa); - } - else + } else nsa = NULL; #ifndef __alpha__ if (linux_sig <= LINUX_SIGTBLSZ) - sa_args.sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; + sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; else #endif - sa_args.sig = linux_sig; + sig = linux_sig; - sa_args.act = nsa; - sa_args.oact = osa; - error = sigaction(td, &sa_args); + error = kern_sigaction(td, sig, nsa, osa, 0); if (error) return (error); Index: sys/compat/linux/linux_socket.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_socket.c,v retrieving revision 1.32 diff -u -r1.32 linux_socket.c --- sys/compat/linux/linux_socket.c 2 Jun 2002 20:05:42 -0000 1.32 +++ sys/compat/linux/linux_socket.c 1 Sep 2002 16:44:20 -0000 @@ -210,36 +210,24 @@ static int linux_check_hdrincl(struct thread *td, int s) { - struct getsockopt_args /* { - int s; - int level; - int name; - caddr_t val; - int *avalsize; - } */ bsd_args; - int error; - caddr_t sg, val, valsize; - int size_val = sizeof val; - int optval; - - sg = stackgap_init(); - val = stackgap_alloc(&sg, sizeof(int)); - valsize = stackgap_alloc(&sg, sizeof(int)); - - if ((error = copyout(&size_val, valsize, sizeof(size_val)))) - return (error); + struct sockopt sopt; + struct socket *so; + int error, optval; - bsd_args.s = s; - bsd_args.level = IPPROTO_IP; - bsd_args.name = IP_HDRINCL; - bsd_args.val = val; - bsd_args.avalsize = (int *)valsize; - if ((error = getsockopt(td, &bsd_args))) + if ((error = fgetsock(td, s, &so, NULL)) != 0) return (error); + sopt.sopt_dir = SOPT_GET; + sopt.sopt_level = IPPROTO_IP; + sopt.sopt_name = IP_HDRINCL; + sopt.sopt_val = &optval; + sopt.sopt_valsize = sizeof(optval); + sopt.sopt_td = td; + sopt.sopt_segflg = SOPT_SYSSPACE; + error = sogetopt(so, &sopt); + fputsock(so); - if ((error = copyin(val, &optval, sizeof(optval)))) + if (error) return (error); - return (optval == 0); } @@ -345,28 +333,22 @@ && bsd_args.domain == AF_INET && retval_socket >= 0) { /* It's a raw IP socket: set the IP_HDRINCL option. */ - struct setsockopt_args /* { - int s; - int level; - int name; - caddr_t val; - int valsize; - } */ bsd_setsockopt_args; - caddr_t sg; - int *hdrincl; - - sg = stackgap_init(); - hdrincl = (int *)stackgap_alloc(&sg, sizeof(*hdrincl)); - *hdrincl = 1; - bsd_setsockopt_args.s = td->td_retval[0]; - bsd_setsockopt_args.level = IPPROTO_IP; - bsd_setsockopt_args.name = IP_HDRINCL; - bsd_setsockopt_args.val = (caddr_t)hdrincl; - bsd_setsockopt_args.valsize = sizeof(*hdrincl); - /* We ignore any error returned by setsockopt() */ - setsockopt(td, &bsd_setsockopt_args); - /* Copy back the return value from socket() */ - td->td_retval[0] = bsd_setsockopt_args.s; + struct sockopt sopt; + struct socket *so; + int hdrincl; + + hdrincl = 1; + if ((error = fgetsock(td, td->td_retval[0], &so, NULL)) != 0) + return (error); + sopt.sopt_dir = SOPT_SET; + sopt.sopt_level = IPPROTO_IP; + sopt.sopt_name = IP_HDRINCL; + sopt.sopt_val = &hdrincl; + sopt.sopt_valsize = sizeof(hdrincl); + sopt.sopt_td = td; + sopt.sopt_segflg = SOPT_SYSSPACE; + (void)sosetopt(so, &sopt); + fputsock(so); } return (retval_socket); Index: sys/compat/linux/linux_stats.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_stats.c,v retrieving revision 1.44 diff -u -r1.44 linux_stats.c --- sys/compat/linux/linux_stats.c 16 Aug 2002 12:51:51 -0000 1.44 +++ sys/compat/linux/linux_stats.c 1 Sep 2002 16:44:20 -0000 @@ -94,20 +94,19 @@ { struct stat buf; struct nameidata nd; + char *path; int error; - caddr_t sg; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(newstat)) - printf(ARGS(newstat, "%s, *"), args->path); + printf(ARGS(newstat, "%s, *"), path); #endif - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, - args->path, td); + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_SYSSPACE, path, td); error = namei(&nd); + LFREEPATH(path); if (error) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -126,19 +125,19 @@ int error; struct stat sb; struct nameidata nd; - caddr_t sg; + char *path; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(newlstat)) - printf(ARGS(newlstat, "%s, *"), args->path); + printf(ARGS(newlstat, "%s, *"), path); #endif - NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, - args->path, td); + NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_SYSSPACE, path, + td); error = namei(&nd); + LFREEPATH(path); if (error) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -231,19 +230,19 @@ struct statfs *bsd_statfs; struct nameidata nd; struct l_statfs linux_statfs; + char *path; int error; - caddr_t sg; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(statfs)) - printf(ARGS(statfs, "%s, *"), args->path); + printf(ARGS(statfs, "%s, *"), path); #endif ndp = &nd; - NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args->path, curthread); + NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, path, td); error = namei(ndp); + LFREEPATH(path); if (error) return error; NDFREE(ndp, NDF_ONLY_PNBUF); @@ -416,19 +415,19 @@ struct stat buf; struct nameidata nd; int error; - caddr_t sg; + char *filename; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->filename); + LCONVPATHEXIST(td, args->filename, &filename); #ifdef DEBUG if (ldebug(stat64)) - printf(ARGS(stat64, "%s, *"), args->filename); + printf(ARGS(stat64, "%s, *"), filename); #endif - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, - args->filename, td); + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_SYSSPACE, filename, + td); error = namei(&nd); + LFREEPATH(filename); if (error) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -447,19 +446,19 @@ int error; struct stat sb; struct nameidata nd; - caddr_t sg; + char *filename; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->filename); + LCONVPATHEXIST(td, args->filename, &filename); #ifdef DEBUG if (ldebug(lstat64)) printf(ARGS(lstat64, "%s, *"), args->filename); #endif - NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, - args->filename, td); + NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_SYSSPACE, filename, + td); error = namei(&nd); + LFREEPATH(filename); if (error) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); Index: sys/compat/linux/linux_sysctl.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_sysctl.c,v retrieving revision 1.2 diff -u -r1.2 linux_sysctl.c --- sys/compat/linux/linux_sysctl.c 12 Sep 2001 08:36:57 -0000 1.2 +++ sys/compat/linux/linux_sysctl.c 1 Sep 2002 16:44:21 -0000 @@ -80,20 +80,20 @@ struct l___sysctl_args la; l_int *mib; int error, i; - caddr_t sg; error = copyin((caddr_t)args->args, &la, sizeof(la)); if (error) return (error); - if (la.nlen == 0 || la.nlen > LINUX_CTL_MAXNAME) + if (la.nlen <= 0 || la.nlen > LINUX_CTL_MAXNAME) return (ENOTDIR); - sg = stackgap_init(); - mib = stackgap_alloc(&sg, la.nlen * sizeof(l_int)); + mib = malloc(la.nlen * sizeof(l_int), M_TEMP, M_WAITOK); error = copyin(la.name, mib, la.nlen * sizeof(l_int)); - if (error) + if (error) { + free(mib, M_TEMP); return (error); + } switch (mib[0]) { case LINUX_CTL_KERN: @@ -102,7 +102,9 @@ switch (mib[1]) { case LINUX_KERN_VERSION: - return (handle_string(&la, version)); + error = handle_string(&la, version); + free(mib, M_TEMP); + return (error); default: break; } @@ -116,5 +118,6 @@ printf("%c%d", (i) ? ',' : '{', mib[i]); printf("}\n"); + free(mib, M_TEMP); return (ENOTDIR); } Index: sys/compat/linux/linux_uid16.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_uid16.c,v retrieving revision 1.7 diff -u -r1.7 linux_uid16.c --- sys/compat/linux/linux_uid16.c 13 Apr 2002 23:11:23 -0000 1.7 +++ sys/compat/linux/linux_uid16.c 1 Sep 2002 16:44:21 -0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -44,48 +45,43 @@ DUMMY(getresuid16); DUMMY(getresgid16); -#define CAST_NOCHG(x) (x == 0xFFFF) ? -1 : x; +#define CAST_NOCHG(x) ((x == 0xFFFF) ? -1 : x) int linux_chown16(struct thread *td, struct linux_chown16_args *args) { - struct chown_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(chown16)) - printf(ARGS(chown16, "%s, %d, %d"), args->path, args->uid, - args->gid); + printf(ARGS(chown16, "%s, %d, %d"), path, args->uid, args->gid); #endif - - bsd.path = args->path; - bsd.uid = CAST_NOCHG(args->uid); - bsd.gid = CAST_NOCHG(args->gid); - return (chown(td, &bsd)); + error = kern_chown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid), + CAST_NOCHG(args->gid)); + LFREEPATH(path); + return (error); } int linux_lchown16(struct thread *td, struct linux_lchown16_args *args) { - struct lchown_args bsd; - caddr_t sg; + char *path; + int error; - sg = stackgap_init(); - CHECKALTEXIST(td, &sg, args->path); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG if (ldebug(lchown16)) - printf(ARGS(lchown16, "%s, %d, %d"), args->path, args->uid, + printf(ARGS(lchown16, "%s, %d, %d"), path, args->uid, args->gid); #endif - - bsd.path = args->path; - bsd.uid = CAST_NOCHG(args->uid); - bsd.gid = CAST_NOCHG(args->gid); - return (lchown(td, &bsd)); + error = kern_lchown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid), + CAST_NOCHG(args->gid)); + LFREEPATH(path); + return (error); } int Index: sys/compat/linux/linux_util.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_util.c,v retrieving revision 1.18 diff -u -r1.18 linux_util.c --- sys/compat/linux/linux_util.c 27 Feb 2002 18:31:41 -0000 1.18 +++ sys/compat/linux/linux_util.c 1 Sep 2002 16:44:21 -0000 @@ -57,6 +57,39 @@ char **pbuf; int cflag; { + char *newpath; + size_t sz; + int error; + + error = linux_emul_convpath(td, path, (sgp == NULL) ? UIO_SYSSPACE : + UIO_USERSPACE, &newpath, cflag); + if (newpath == NULL) + return (error); + + if (sgp == NULL) { + *pbuf = newpath; + return (error); + } + + sz = strlen(newpath); + *pbuf = stackgap_alloc(sgp, sz + 1); + if (*pbuf != NULL) + error = copyout(newpath, *pbuf, sz + 1); + else + error = ENAMETOOLONG; + free(newpath, M_TEMP); + + return (error); +} + +int +linux_emul_convpath(td, path, pathseg, pbuf, cflag) + struct thread *td; + char *path; + enum uio_seg pathseg; + char **pbuf; + int cflag; +{ struct nameidata nd; struct nameidata ndroot; struct vattr vat; @@ -64,32 +97,30 @@ int error; const char *prefix; char *ptr, *buf, *cp; - size_t sz, len; + size_t len, sz; buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - *pbuf = path; + *pbuf = buf; prefix = linux_emul_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) + if (pathseg == UIO_SYSSPACE) error = copystr(path, ptr, sz, &len); else error = copyinstr(path, ptr, sz, &len); if (error) { + *pbuf = NULL; free(buf, M_TEMP); return error; } if (*ptr != '/') { - free(buf, M_TEMP); - return EINVAL; + error = EINVAL; + goto keeporig; } /* @@ -105,21 +136,16 @@ *cp = '\0'; NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); - - if ((error = namei(&nd)) != 0) { - free(buf, M_TEMP); - return error; - } - + error = namei(&nd); *cp = '/'; + if (error != 0) + goto keeporig; } else { NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); - if ((error = namei(&nd)) != 0) { - free(buf, M_TEMP); - return error; - } + if ((error = namei(&nd)) != 0) + goto keeporig; /* * We now compare the vnode of the linux_root to the one @@ -134,10 +160,9 @@ if ((error = namei(&ndroot)) != 0) { /* Cannot happen! */ - free(buf, M_TEMP); NDFREE(&nd, NDF_ONLY_PNBUF); vrele(nd.ni_vp); - return error; + goto keeporig; } if ((error = VOP_GETATTR(nd.ni_vp, &vat, td->td_ucred, td)) != 0) { @@ -156,17 +181,6 @@ } } - if (sgp == NULL) - *pbuf = buf; - else { - sz = &ptr[len] - buf; - *pbuf = stackgap_alloc(sgp, sz + 1); - if (*pbuf != NULL) - error = copyout(buf, *pbuf, sz); - else - error = ENAMETOOLONG; - free(buf, M_TEMP); - } NDFREE(&nd, NDF_ONLY_PNBUF); vrele(nd.ni_vp); @@ -181,6 +195,8 @@ vrele(ndroot.ni_vp); NDFREE(&nd, NDF_ONLY_PNBUF); vrele(nd.ni_vp); - free(buf, M_TEMP); +keeporig: + /* Keep the original path; copy it back to the start of the buffer. */ + bcopy(ptr, buf, len); return error; } Index: sys/compat/linux/linux_util.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/compat/linux/linux_util.h,v retrieving revision 1.18 diff -u -r1.18 linux_util.h --- sys/compat/linux/linux_util.h 20 Mar 2002 05:42:02 -0000 1.18 +++ sys/compat/linux/linux_util.h 1 Sep 2002 16:44:21 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include static __inline caddr_t stackgap_init(void); static __inline void *stackgap_alloc(caddr_t *, size_t); @@ -75,6 +76,7 @@ extern const char linux_emul_path[]; int linux_emul_find(struct thread *, caddr_t *, char *, char **, int); +int linux_emul_convpath(struct thread *, char *, enum uio_seg, char **, int); #define CHECKALT(p, sgp, path, i) \ do { \ @@ -87,6 +89,20 @@ #define CHECKALTEXIST(p, sgp, path) CHECKALT(p, sgp, path, 0) #define CHECKALTCREAT(p, sgp, path) CHECKALT(p, sgp, path, 1) + +#define LCONVPATH(td, upath, pathp, i) \ + do { \ + int _error; \ + \ + _error = linux_emul_convpath(td, upath, UIO_USERSPACE, \ + pathp, i); \ + if (*(pathp) == NULL) \ + return (_error); \ + } while (0) + +#define LCONVPATHEXIST(td, upath, pathp) LCONVPATH(td, upath, pathp, 0) +#define LCONVPATHCREAT(td, upath, pathp) LCONVPATH(td, upath, pathp, 1) +#define LFREEPATH(path) free(path, M_TEMP) #define DUMMY(s) \ int \ Index: sys/i386/linux/linux_machdep.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/i386/linux/linux_machdep.c,v retrieving revision 1.27 diff -u -r1.27 linux_machdep.c --- sys/i386/linux/linux_machdep.c 29 Jun 2002 17:26:17 -0000 1.27 +++ sys/i386/linux/linux_machdep.c 1 Sep 2002 16:44:21 -0000 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -685,22 +686,18 @@ int linux_sigsuspend(struct thread *td, struct linux_sigsuspend_args *args) { - struct sigsuspend_args bsd; - sigset_t *sigmask; + sigset_t sigmask; l_sigset_t mask; - caddr_t sg = stackgap_init(); #ifdef DEBUG if (ldebug(sigsuspend)) printf(ARGS(sigsuspend, "%08lx"), (unsigned long)args->mask); #endif - sigmask = stackgap_alloc(&sg, sizeof(sigset_t)); LINUX_SIGEMPTYSET(mask); mask.__bits[0] = args->mask; - linux_to_bsd_sigset(&mask, sigmask); - bsd.sigmask = sigmask; - return (sigsuspend(td, &bsd)); + linux_to_bsd_sigset(&mask, &sigmask); + return (kern_sigsuspend(td, sigmask)); } int @@ -709,9 +706,7 @@ struct linux_rt_sigsuspend_args *uap; { l_sigset_t lmask; - sigset_t *bmask; - struct sigsuspend_args bsd; - caddr_t sg = stackgap_init(); + sigset_t sigmask; int error; #ifdef DEBUG @@ -727,71 +722,54 @@ if (error) return (error); - bmask = stackgap_alloc(&sg, sizeof(sigset_t)); - linux_to_bsd_sigset(&lmask, bmask); - bsd.sigmask = bmask; - return (sigsuspend(td, &bsd)); + linux_to_bsd_sigset(&lmask, &sigmask); + return (kern_sigsuspend(td, sigmask)); } int linux_pause(struct thread *td, struct linux_pause_args *args) { struct proc *p = td->td_proc; - struct sigsuspend_args bsd; - sigset_t *sigmask; - caddr_t sg = stackgap_init(); + sigset_t sigmask; #ifdef DEBUG if (ldebug(pause)) printf(ARGS(pause, "")); #endif - sigmask = stackgap_alloc(&sg, sizeof(sigset_t)); PROC_LOCK(p); - *sigmask = p->p_sigmask; + sigmask = p->p_sigmask; PROC_UNLOCK(p); - bsd.sigmask = sigmask; - return (sigsuspend(td, &bsd)); + return (kern_sigsuspend(td, sigmask)); } int linux_sigaltstack(struct thread *td, struct linux_sigaltstack_args *uap) { - struct sigaltstack_args bsd; - stack_t *ss, *oss; + stack_t ss, oss; l_stack_t lss; int error; - caddr_t sg = stackgap_init(); #ifdef DEBUG if (ldebug(sigaltstack)) printf(ARGS(sigaltstack, "%p, %p"), uap->uss, uap->uoss); #endif - if (uap->uss == NULL) { - ss = NULL; - } else { + if (uap->uss != NULL) { error = copyin(uap->uss, &lss, sizeof(l_stack_t)); if (error) return (error); - ss = stackgap_alloc(&sg, sizeof(stack_t)); - ss->ss_sp = lss.ss_sp; - ss->ss_size = lss.ss_size; - ss->ss_flags = linux_to_bsd_sigaltstack(lss.ss_flags); - } - oss = (uap->uoss != NULL) - ? stackgap_alloc(&sg, sizeof(stack_t)) - : NULL; - - bsd.ss = ss; - bsd.oss = oss; - error = sigaltstack(td, &bsd); - - if (!error && oss != NULL) { - lss.ss_sp = oss->ss_sp; - lss.ss_size = oss->ss_size; - lss.ss_flags = bsd_to_linux_sigaltstack(oss->ss_flags); + ss.ss_sp = lss.ss_sp; + ss.ss_size = lss.ss_size; + ss.ss_flags = linux_to_bsd_sigaltstack(lss.ss_flags); + } + error = kern_sigaltstack(td, (uap->uoss != NULL) ? &oss : NULL, + (uap->uss != NULL) ? &ss : NULL); + if (!error && uap->uoss != NULL) { + lss.ss_sp = oss.ss_sp; + lss.ss_size = oss.ss_size; + lss.ss_flags = bsd_to_linux_sigaltstack(oss.ss_flags); error = copyout(&lss, uap->uoss, sizeof(l_stack_t)); } Index: sys/i386/linux/linux_ptrace.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/i386/linux/linux_ptrace.c,v retrieving revision 1.3 diff -u -r1.3 linux_ptrace.c --- sys/i386/linux/linux_ptrace.c 29 Jun 2002 17:26:17 -0000 1.3 +++ sys/i386/linux/linux_ptrace.c 1 Sep 2002 16:44:21 -0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -246,119 +247,92 @@ int linux_ptrace(struct thread *td, struct linux_ptrace_args *uap) { - struct ptrace_args bsd_args; - int error; - caddr_t sg; union { struct linux_pt_reg reg; struct linux_pt_fpreg fpreg; struct linux_pt_fpxreg fpxreg; } r; - - sg = stackgap_init(); + union { + struct reg bsd_reg; + struct fpreg bsd_fpreg; + struct dbreg bsd_dbreg; + } u; + void *addr; + pid_t pid; + int error, req; error = 0; /* by default, just copy data intact */ - bsd_args.req = uap->req; - bsd_args.pid = (pid_t)uap->pid; - bsd_args.addr = (caddr_t)uap->addr; - bsd_args.data = uap->data; + req = uap->req; + pid = (pid_t)uap->pid; + addr = (void *)uap->addr; - switch (uap->req) { + switch (req) { case PTRACE_TRACEME: case PTRACE_POKETEXT: case PTRACE_POKEDATA: case PTRACE_KILL: - error = ptrace(td, &bsd_args); + error = kern_ptrace(td, req, pid, addr, uap->data); break; case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: { /* need to preserve return value */ int rval = td->td_retval[0]; - bsd_args.data = 0; - error = ptrace(td, &bsd_args); + error = kern_ptrace(td, req, pid, addr, 0); if (error == 0) - error = copyout(td->td_retval, - (caddr_t)uap->data, sizeof(l_int)); + error = copyout(td->td_retval, (caddr_t)uap->data, + sizeof(l_int)); td->td_retval[0] = rval; break; } case PTRACE_DETACH: - bsd_args.req = PT_DETACH; - /* fall through */ + error = kern_ptrace(td, PT_DETACH, pid, (void *)1, + map_signum(uap->data)); + break; case PTRACE_SINGLESTEP: case PTRACE_CONT: - bsd_args.data = map_signum(uap->data); - bsd_args.addr = (caddr_t)1; - error = ptrace(td, &bsd_args); + error = kern_ptrace(td, req, pid, (void *)1, + map_signum(uap->data)); break; case PTRACE_ATTACH: - bsd_args.req = PT_ATTACH; - error = ptrace(td, &bsd_args); + error = kern_ptrace(td, PT_ATTACH, pid, addr, uap->data); break; - case PTRACE_GETREGS: { - struct reg *bsd_r; - - bsd_r = (struct reg*)stackgap_alloc(&sg, sizeof(*bsd_r)); + case PTRACE_GETREGS: /* Linux is using data where FreeBSD is using addr */ - bsd_args.req = PT_GETREGS; - bsd_args.addr = (caddr_t)bsd_r; - bsd_args.data = 0; - error = ptrace(td, &bsd_args); + error = kern_ptrace(td, PT_GETREGS, pid, &u.bsd_reg, 0); if (error == 0) { - map_regs_to_linux(bsd_r, &r.reg); + map_regs_to_linux(&u.bsd_reg, &r.reg); error = copyout(&r.reg, (caddr_t)uap->data, sizeof(r.reg)); } break; - } - case PTRACE_SETREGS: { - struct reg *bsd_r; - - bsd_r = (struct reg*)stackgap_alloc(&sg, sizeof(*bsd_r)); + case PTRACE_SETREGS: /* Linux is using data where FreeBSD is using addr */ - bsd_args.req = PT_SETREGS; - bsd_args.addr = (caddr_t)bsd_r; - bsd_args.data = 0; error = copyin((caddr_t)uap->data, &r.reg, sizeof(r.reg)); if (error == 0) { - map_regs_from_linux(bsd_r, &r.reg); - error = ptrace(td, &bsd_args); + map_regs_from_linux(&u.bsd_reg, &r.reg); + error = kern_ptrace(td, PT_SETREGS, pid, &u.bsd_reg, 0); } break; - } - case PTRACE_GETFPREGS: { - struct fpreg *bsd_r; - - bsd_r = (struct fpreg*)stackgap_alloc(&sg, sizeof(*bsd_r)); + case PTRACE_GETFPREGS: /* Linux is using data where FreeBSD is using addr */ - bsd_args.req = PT_GETFPREGS; - bsd_args.addr = (caddr_t)bsd_r; - bsd_args.data = 0; - error = ptrace(td, &bsd_args); + error = kern_ptrace(td, PT_GETFPREGS, pid, &u.bsd_fpreg, 0); if (error == 0) { - map_fpregs_to_linux(bsd_r, &r.fpreg); + map_fpregs_to_linux(&u.bsd_fpreg, &r.fpreg); error = copyout(&r.fpreg, (caddr_t)uap->data, sizeof(r.fpreg)); } break; - } - case PTRACE_SETFPREGS: { - struct fpreg *bsd_r; - - bsd_r = (struct fpreg*)stackgap_alloc(&sg, sizeof(*bsd_r)); + case PTRACE_SETFPREGS: /* Linux is using data where FreeBSD is using addr */ - bsd_args.req = PT_SETFPREGS; - bsd_args.addr = (caddr_t)bsd_r; - bsd_args.data = 0; error = copyin((caddr_t)uap->data, &r.fpreg, sizeof(r.fpreg)); if (error == 0) { - map_fpregs_from_linux(bsd_r, &r.fpreg); - error = ptrace(td, &bsd_args); + map_fpregs_from_linux(&u.bsd_fpreg, &r.fpreg); + error = kern_ptrace(td, PT_SETFPREGS, pid, + &u.bsd_fpreg, 0); } break; - } case PTRACE_SETFPXREGS: #ifdef CPU_ENABLE_SSA error = copyin((caddr_t)uap->data, &r.fpxreg, @@ -415,7 +389,7 @@ } td2 = FIRST_THREAD_IN_PROC(p); - if (uap->req == PTRACE_GETFPXREGS) { + if (req == PTRACE_GETFPXREGS) { _PHOLD(p); error = linux_proc_read_fpxregs(td2, &r.fpxreg); _PRELE(p); @@ -453,20 +427,12 @@ * as necessary. */ if (uap->addr < sizeof(struct linux_pt_reg)) { - struct reg *bsd_r; - - bsd_r = (struct reg*)stackgap_alloc(&sg, - sizeof(*bsd_r)); - bsd_args.req = PT_GETREGS; - bsd_args.addr = (caddr_t)bsd_r; - bsd_args.data = 0; - - error = ptrace(td, &bsd_args); + error = kern_ptrace(td, PT_GETREGS, pid, &u.bsd_reg, 0); if (error != 0) break; - map_regs_to_linux(bsd_r, &r.reg); - if (uap->req == PTRACE_PEEKUSR) { + map_regs_to_linux(&u.bsd_reg, &r.reg); + if (req == PTRACE_PEEKUSR) { error = copyout((char *)&r.reg + uap->addr, (caddr_t)uap->data, sizeof(l_int)); break; @@ -475,11 +441,8 @@ *(l_int *)((char *)&r.reg + uap->addr) = (l_int)uap->data; - map_regs_from_linux(bsd_r, &r.reg); - bsd_args.req = PT_SETREGS; - bsd_args.addr = (caddr_t)bsd_r; - bsd_args.data = 0; - error = ptrace(td, &bsd_args); + map_regs_from_linux(&u.bsd_reg, &r.reg); + error = kern_ptrace(td, PT_SETREGS, pid, &u.bsd_reg, 0); } /* @@ -487,29 +450,23 @@ */ if (uap->addr >= LINUX_DBREG_OFFSET && uap->addr <= LINUX_DBREG_OFFSET + LINUX_DBREG_SIZE) { - struct dbreg *bsd_r; - - bsd_r = (struct dbreg*)stackgap_alloc(&sg, - sizeof(*bsd_r)); - bsd_args.req = PT_GETDBREGS; - bsd_args.addr = (caddr_t)bsd_r; - bsd_args.data = 0; - error = ptrace(td, &bsd_args); + error = kern_ptrace(td, PT_GETDBREGS, pid, &u.bsd_dbreg, + 0); if (error != 0) break; uap->addr -= LINUX_DBREG_OFFSET; - if (uap->req == PTRACE_PEEKUSR) { - error = copyout((char *)bsd_r + uap->addr, - (caddr_t)uap->data, sizeof(l_int)); + if (req == PTRACE_PEEKUSR) { + error = copyout((char *)&u.bsd_dbreg + + uap->addr, (caddr_t)uap->data, + sizeof(l_int)); break; } - *(l_int *)((char *)bsd_r + uap->addr) = uap->data; - bsd_args.req = PT_SETDBREGS; - bsd_args.addr = (caddr_t)bsd_r; - bsd_args.data = 0; - error = ptrace(td, &bsd_args); + *(l_int *)((char *)&u.bsd_dbreg + uap->addr) = + uap->data; + error = kern_ptrace(td, PT_SETDBREGS, pid, + &u.bsd_dbreg, 0); } break; Index: sys/i386/linux/linux_sysvec.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/i386/linux/linux_sysvec.c,v retrieving revision 1.101 diff -u -r1.101 linux_sysvec.c --- sys/i386/linux/linux_sysvec.c 20 Jul 2002 02:56:10 -0000 1.101 +++ sys/i386/linux/linux_sysvec.c 1 Sep 2002 16:44:21 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -597,14 +598,12 @@ struct linux_rt_sigreturn_args *args; { struct proc *p = td->td_proc; - struct sigaltstack_args sasargs; struct l_ucontext uc; struct l_sigcontext *context; l_stack_t *lss; - stack_t *ss; + stack_t ss; register struct trapframe *regs; int eflags; - caddr_t sg = stackgap_init(); regs = td->td_frame; @@ -681,20 +680,17 @@ /* * call sigaltstack & ignore results.. */ - ss = stackgap_alloc(&sg, sizeof(stack_t)); lss = &uc.uc_stack; - ss->ss_sp = lss->ss_sp; - ss->ss_size = lss->ss_size; - ss->ss_flags = linux_to_bsd_sigaltstack(lss->ss_flags); + ss.ss_sp = lss->ss_sp; + ss.ss_size = lss->ss_size; + ss.ss_flags = linux_to_bsd_sigaltstack(lss->ss_flags); #ifdef DEBUG if (ldebug(rt_sigreturn)) printf(LMSG("rt_sigret flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"), - ss->ss_flags, ss->ss_sp, ss->ss_size, context->sc_mask); + ss.ss_flags, ss.ss_sp, ss.ss_size, context->sc_mask); #endif - sasargs.ss = ss; - sasargs.oss = NULL; - (void) sigaltstack(td, &sasargs); + (void)kern_sigaltstack(td, &ss, NULL); return (EJUSTRETURN); } Index: sys/kern/init_main.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/init_main.c,v retrieving revision 1.202 diff -u -r1.202 init_main.c --- sys/kern/init_main.c 7 Aug 2002 17:53:31 -0000 1.202 +++ sys/kern/init_main.c 1 Sep 2002 16:44:21 -0000 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -529,7 +530,7 @@ * since the fs will be read-only. But a NFS root * might be ok. It is worth a shot. */ - error = vn_mkdir("/dev", 0700, UIO_SYSSPACE, td); + error = kern_mkdir(td, "/dev", UIO_SYSSPACE, 0700); if (error == EEXIST) error = 0; if (error == 0) Index: sys/kern/kern_descrip.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/kern_descrip.c,v retrieving revision 1.156 diff -u -r1.156 kern_descrip.c --- sys/kern/kern_descrip.c 25 Aug 2002 13:17:21 -0000 1.156 +++ sys/kern/kern_descrip.c 1 Sep 2002 16:44:21 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -249,17 +250,49 @@ */ /* ARGSUSED */ int -fcntl(td, uap) - struct thread *td; - register struct fcntl_args *uap; +fcntl(struct thread *td, struct fcntl_args *uap) +{ + struct flock fl; + intptr_t arg; + int error; + + error = 0; + switch (uap->cmd) { + case F_SETLK: + case F_GETLK: + error = copyin((caddr_t)(intptr_t)uap->arg, &fl, sizeof(fl)); + arg = (intptr_t)&fl; + break; + default: + arg = uap->arg; + break; + } + if (error) + return (error); + + error = kern_fcntl(td, uap->fd, uap->cmd, arg); + if (error) + return (error); + + switch (uap->cmd) { + case F_GETLK: + error = copyout(&fl, (caddr_t)(intptr_t)uap->arg, sizeof(fl)); + break; + } + + return (error); +} + +int +kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) { register struct proc *p = td->td_proc; register struct filedesc *fdp; register struct file *fp; register char *pop; struct vnode *vp; + struct flock *flp; int i, tmp, error = 0, flg = F_POSIX; - struct flock fl; u_int newmin; struct proc *leaderp; @@ -267,17 +300,17 @@ fdp = p->p_fd; FILEDESC_LOCK(fdp); - if ((unsigned)uap->fd >= fdp->fd_nfiles || - (fp = fdp->fd_ofiles[uap->fd]) == NULL) { + if ((unsigned)fd >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[fd]) == NULL) { FILEDESC_UNLOCK(fdp); error = EBADF; goto done2; } - pop = &fdp->fd_ofileflags[uap->fd]; + pop = &fdp->fd_ofileflags[fd]; - switch (uap->cmd) { + switch (cmd) { case F_DUPFD: - newmin = uap->arg; + newmin = arg; if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || newmin >= maxfilesperproc) { FILEDESC_UNLOCK(fdp); @@ -288,7 +321,7 @@ FILEDESC_UNLOCK(fdp); break; } - error = do_dup(fdp, uap->fd, i, td->td_retval, td); + error = do_dup(fdp, fd, i, td->td_retval, td); break; case F_GETFD: @@ -298,7 +331,7 @@ case F_SETFD: *pop = (*pop &~ UF_EXCLOSE) | - (uap->arg & FD_CLOEXEC ? UF_EXCLOSE : 0); + (arg & FD_CLOEXEC ? UF_EXCLOSE : 0); FILEDESC_UNLOCK(fdp); break; @@ -313,7 +346,7 @@ fhold(fp); FILEDESC_UNLOCK(fdp); fp->f_flag &= ~FCNTLFLAGS; - fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS; + fp->f_flag |= FFLAGS(arg & ~O_ACCMODE) & FCNTLFLAGS; tmp = fp->f_flag & FNONBLOCK; error = fo_ioctl(fp, FIONBIO, &tmp, td->td_ucred, td); if (error) { @@ -343,7 +376,7 @@ case F_SETOWN: fhold(fp); FILEDESC_UNLOCK(fdp); - error = fo_ioctl(fp, FIOSETOWN, &uap->arg, td->td_ucred, td); + error = fo_ioctl(fp, FIOSETOWN, &arg, td->td_ucred, td); fdrop(fp, td); break; @@ -357,32 +390,26 @@ error = EBADF; break; } - vp = (struct vnode *)fp->f_data; - /* - * copyin/lockop may block - */ - fhold(fp); - FILEDESC_UNLOCK(fdp); - vp = (struct vnode *)fp->f_data; - - /* Copy in the lock structure */ - error = copyin((caddr_t)(intptr_t)uap->arg, &fl, sizeof(fl)); - if (error) { - fdrop(fp, td); - break; - } - if (fl.l_whence == SEEK_CUR) { + flp = (struct flock *)arg; + if (flp->l_whence == SEEK_CUR) { if (fp->f_offset < 0 || - (fl.l_start > 0 && - fp->f_offset > OFF_MAX - fl.l_start)) { - fdrop(fp, td); + (flp->l_start > 0 && + fp->f_offset > OFF_MAX - flp->l_start)) { + FILEDESC_UNLOCK(fdp); error = EOVERFLOW; break; } - fl.l_start += fp->f_offset; + flp->l_start += fp->f_offset; } - switch (fl.l_type) { + /* + * lockop may block + */ + fhold(fp); + FILEDESC_UNLOCK(fdp); + vp = (struct vnode *)fp->f_data; + + switch (flp->l_type) { case F_RDLCK: if ((fp->f_flag & FREAD) == 0) { error = EBADF; @@ -393,7 +420,7 @@ leaderp = p->p_leader; PROC_UNLOCK(p); error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_SETLK, - &fl, flg); + flp, flg); break; case F_WRLCK: if ((fp->f_flag & FWRITE) == 0) { @@ -404,15 +431,15 @@ p->p_flag |= P_ADVLOCK; leaderp = p->p_leader; PROC_UNLOCK(p); - error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_SETLK, - &fl, flg); + error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_SETLK, flp, + flg); break; case F_UNLCK: PROC_LOCK(p); leaderp = p->p_leader; PROC_UNLOCK(p); - error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_UNLCK, - &fl, F_POSIX); + error = VOP_ADVLOCK(vp, (caddr_t)leaderp, F_UNLCK, flp, + F_POSIX); break; default: error = EINVAL; @@ -427,44 +454,33 @@ error = EBADF; break; } - vp = (struct vnode *)fp->f_data; - /* - * copyin/lockop may block - */ - fhold(fp); - FILEDESC_UNLOCK(fdp); - vp = (struct vnode *)fp->f_data; - - /* Copy in the lock structure */ - error = copyin((caddr_t)(intptr_t)uap->arg, &fl, sizeof(fl)); - if (error) { - fdrop(fp, td); - break; - } - if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK && - fl.l_type != F_UNLCK) { - fdrop(fp, td); + flp = (struct flock *)arg; + if (flp->l_type != F_RDLCK && flp->l_type != F_WRLCK && + flp->l_type != F_UNLCK) { + FILEDESC_UNLOCK(fdp); error = EINVAL; break; } - if (fl.l_whence == SEEK_CUR) { - if ((fl.l_start > 0 && - fp->f_offset > OFF_MAX - fl.l_start) || - (fl.l_start < 0 && - fp->f_offset < OFF_MIN - fl.l_start)) { - fdrop(fp, td); + if (flp->l_whence == SEEK_CUR) { + if ((flp->l_start > 0 && + fp->f_offset > OFF_MAX - flp->l_start) || + (flp->l_start < 0 && + fp->f_offset < OFF_MIN - flp->l_start)) { + FILEDESC_UNLOCK(fdp); error = EOVERFLOW; break; } - fl.l_start += fp->f_offset; + flp->l_start += fp->f_offset; } - error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_GETLK, - &fl, F_POSIX); + /* + * lockop may block + */ + fhold(fp); + FILEDESC_UNLOCK(fdp); + vp = (struct vnode *)fp->f_data; + error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_GETLK, flp, + F_POSIX); fdrop(fp, td); - if (error == 0) { - error = copyout(&fl, (caddr_t)(intptr_t)uap->arg, - sizeof(fl)); - } break; default: FILEDESC_UNLOCK(fdp); Index: sys/kern/kern_sig.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/kern_sig.c,v retrieving revision 1.183 diff -u -r1.183 kern_sig.c --- sys/kern/kern_sig.c 26 Aug 2002 05:02:56 -0000 1.183 +++ sys/kern/kern_sig.c 1 Sep 2002 16:44:21 -0000 @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -75,8 +76,6 @@ #define ONSIG 32 /* NSIG for osig* syscalls. XXX. */ static int coredump(struct thread *); -static int do_sigaction(struct proc *p, int sig, struct sigaction *act, - struct sigaction *oact, int old); static int do_sigprocmask(struct proc *p, int how, sigset_t *set, sigset_t *oset, int old); static char *expand_name(const char *, uid_t, pid_t); @@ -221,18 +220,19 @@ } /* - * do_sigaction + * kern_sigaction * sigaction * osigaction */ -static int -do_sigaction(p, sig, act, oact, old) - struct proc *p; +int +kern_sigaction(td, sig, act, oact, old) + struct thread *td; register int sig; struct sigaction *act, *oact; int old; { register struct sigacts *ps; + struct proc *p = td->td_proc; if (!_SIG_VALID(sig)) return (EINVAL); @@ -374,7 +374,6 @@ struct thread *td; register struct sigaction_args *uap; { - struct proc *p = td->td_proc; struct sigaction act, oact; register struct sigaction *actp, *oactp; int error; @@ -388,7 +387,7 @@ if (error) goto done2; } - error = do_sigaction(p, uap->sig, actp, oactp, 0); + error = kern_sigaction(td, uap->sig, actp, oactp, 0); if (oactp && !error) { error = copyout(oactp, uap->oact, sizeof(oact)); } @@ -414,7 +413,6 @@ struct thread *td; register struct osigaction_args *uap; { - struct proc *p = td->td_proc; struct osigaction sa; struct sigaction nsa, osa; register struct sigaction *nsap, *osap; @@ -436,7 +434,7 @@ nsap->sa_flags = sa.sa_flags; OSIG2SIG(sa.sa_mask, nsap->sa_mask); } - error = do_sigaction(p, uap->signum, nsap, osap, 1); + error = kern_sigaction(td, uap->signum, nsap, osap, 1); if (osap && !error) { sa.sa_handler = osap->sa_handler; sa.sa_flags = osap->sa_flags; @@ -689,7 +687,6 @@ struct thread *td; register struct osigvec_args *uap; { - struct proc *p = td->td_proc; struct sigvec vec; struct sigaction nsa, osa; register struct sigaction *nsap, *osap; @@ -712,7 +709,7 @@ #endif } mtx_lock(&Giant); - error = do_sigaction(p, uap->signum, nsap, osap, 1); + error = kern_sigaction(td, uap->signum, nsap, osap, 1); mtx_unlock(&Giant); if (osap && !error) { vec.sv_handler = osap->sa_handler; @@ -806,14 +803,20 @@ struct thread *td; struct sigsuspend_args *uap; { - struct proc *p = td->td_proc; sigset_t mask; - register struct sigacts *ps; int error; error = copyin(uap->sigmask, &mask, sizeof(mask)); if (error) return (error); + return (kern_sigsuspend(td, mask)); +} + +int +kern_sigsuspend(struct thread *td, sigset_t mask) +{ + struct proc *p = td->td_proc; + register struct sigacts *ps; /* * When returning from sigsuspend, we want @@ -939,8 +942,27 @@ struct thread *td; register struct sigaltstack_args *uap; { + stack_t ss, oss; + int error; + + if (uap->ss != NULL) { + error = copyin(uap->ss, &ss, sizeof(ss)); + if (error) + return (error); + } + error = kern_sigaltstack(td, (uap->ss != NULL) ? &ss : NULL, + (uap->oss != NULL) ? &oss : NULL); + if (error) + return (error); + if (uap->oss != NULL) + error = copyout(&oss, uap->oss, sizeof(stack_t)); + return (error); +} + +int +kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss) +{ struct proc *p = td->td_proc; - stack_t ss; int oonstack; int error = 0; @@ -948,34 +970,30 @@ oonstack = sigonstack(cpu_getstack(td)); - if (uap->oss != NULL) { + if (oss != NULL) { PROC_LOCK(p); - ss = p->p_sigstk; - ss.ss_flags = (p->p_flag & P_ALTSTACK) + *oss = p->p_sigstk; + oss->ss_flags = (p->p_flag & P_ALTSTACK) ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; PROC_UNLOCK(p); - if ((error = copyout(&ss, uap->oss, sizeof(stack_t))) != 0) - goto done2; } - if (uap->ss != NULL) { + if (ss != NULL) { if (oonstack) { error = EPERM; goto done2; } - if ((error = copyin(uap->ss, &ss, sizeof(ss))) != 0) - goto done2; - if ((ss.ss_flags & ~SS_DISABLE) != 0) { + if ((ss->ss_flags & ~SS_DISABLE) != 0) { error = EINVAL; goto done2; } - if (!(ss.ss_flags & SS_DISABLE)) { - if (ss.ss_size < p->p_sysent->sv_minsigstksz) { + if (!(ss->ss_flags & SS_DISABLE)) { + if (ss->ss_size < p->p_sysent->sv_minsigstksz) { error = ENOMEM; goto done2; } PROC_LOCK(p); - p->p_sigstk = ss; + p->p_sigstk = *ss; p->p_flag |= P_ALTSTACK; PROC_UNLOCK(p); } else { @@ -1211,7 +1229,7 @@ SIGADDSET(p->p_sigmask, sig); if (SIGISMEMBER(ps->ps_sigreset, sig)) { /* - * See do_sigaction() for origin of this code. + * See kern_sigaction() for origin of this code. */ SIGDELSET(p->p_sigcatch, sig); if (sig != SIGCONT && @@ -1793,7 +1811,7 @@ if (SIGISMEMBER(ps->ps_sigreset, sig)) { /* - * See do_sigaction() for origin of this code. + * See kern_sigaction() for origin of this code. */ SIGDELSET(p->p_sigcatch, sig); if (sig != SIGCONT && Index: sys/kern/sys_generic.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/sys_generic.c,v retrieving revision 1.111 diff -u -r1.111 sys_generic.c --- sys/kern/sys_generic.c 23 Aug 2002 22:43:28 -0000 1.111 +++ sys/kern/sys_generic.c 1 Sep 2002 16:44:21 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -713,6 +714,24 @@ register struct thread *td; register struct select_args *uap; { + struct timeval tv, *tvp; + int error; + + if (uap->tv != NULL) { + error = copyin(uap->tv, &tv, sizeof(tv)); + if (error) + return (error); + tvp = &tv; + } else + tvp = NULL; + + return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); +} + +int +kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, + fd_set *fd_ex, struct timeval *tvp) +{ struct filedesc *fdp; /* * The magic 2048 here is chosen to be just enough for FD_SETSIZE @@ -726,28 +745,28 @@ int error, timo; u_int ncoll, nbufbytes, ncpbytes, nfdbits; - if (uap->nd < 0) + if (nd < 0) return (EINVAL); fdp = td->td_proc->p_fd; mtx_lock(&Giant); FILEDESC_LOCK(fdp); - if (uap->nd > td->td_proc->p_fd->fd_nfiles) - uap->nd = td->td_proc->p_fd->fd_nfiles; /* forgiving; slightly wrong */ + if (nd > td->td_proc->p_fd->fd_nfiles) + nd = td->td_proc->p_fd->fd_nfiles; /* forgiving; slightly wrong */ FILEDESC_UNLOCK(fdp); /* * Allocate just enough bits for the non-null fd_sets. Use the * preallocated auto buffer if possible. */ - nfdbits = roundup(uap->nd, NFDBITS); + nfdbits = roundup(nd, NFDBITS); ncpbytes = nfdbits / NBBY; nbufbytes = 0; - if (uap->in != NULL) + if (fd_in != NULL) nbufbytes += 2 * ncpbytes; - if (uap->ou != NULL) + if (fd_ou != NULL) nbufbytes += 2 * ncpbytes; - if (uap->ex != NULL) + if (fd_ex != NULL) nbufbytes += 2 * ncpbytes; if (nbufbytes <= sizeof s_selbits) selbits = &s_selbits[0]; @@ -762,28 +781,26 @@ sbp = selbits; #define getbits(name, x) \ do { \ - if (uap->name == NULL) \ + if (name == NULL) \ ibits[x] = NULL; \ else { \ ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp; \ obits[x] = sbp; \ sbp += ncpbytes / sizeof *sbp; \ - error = copyin(uap->name, ibits[x], ncpbytes); \ + error = copyin(name, ibits[x], ncpbytes); \ if (error != 0) \ goto done_nosellock; \ } \ } while (0) - getbits(in, 0); - getbits(ou, 1); - getbits(ex, 2); + getbits(fd_in, 0); + getbits(fd_ou, 1); + getbits(fd_ex, 2); #undef getbits if (nbufbytes != 0) bzero(selbits, nbufbytes / 2); - if (uap->tv) { - error = copyin(uap->tv, &atv, sizeof (atv)); - if (error) - goto done_nosellock; + if (tvp != NULL) { + atv = *tvp; if (itimerfix(&atv)) { error = EINVAL; goto done_nosellock; @@ -804,7 +821,7 @@ mtx_unlock_spin(&sched_lock); mtx_unlock(&sellock); - error = selscan(td, ibits, obits, uap->nd); + error = selscan(td, ibits, obits, nd); mtx_lock(&sellock); if (error || td->td_retval[0]) goto done; @@ -853,14 +870,14 @@ if (error == EWOULDBLOCK) error = 0; #define putbits(name, x) \ - if (uap->name && (error2 = copyout(obits[x], uap->name, ncpbytes))) \ + if (name && (error2 = copyout(obits[x], name, ncpbytes))) \ error = error2; if (error == 0) { int error2; - putbits(in, 0); - putbits(ou, 1); - putbits(ex, 2); + putbits(fd_in, 0); + putbits(fd_ou, 1); + putbits(fd_ex, 2); #undef putbits } if (selbits != &s_selbits[0]) Index: sys/kern/sys_process.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/sys_process.c,v retrieving revision 1.99 diff -u -r1.99 sys_process.c --- sys/kern/sys_process.c 25 Aug 2002 13:17:21 -0000 1.99 +++ sys/kern/sys_process.c 1 Sep 2002 16:44:21 -0000 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -324,8 +325,6 @@ int ptrace(struct thread *td, struct ptrace_args *uap) { - struct iovec iov; - struct uio uio; /* * XXX this obfuscation is to reduce stack usage, but the register * structs may be too large to put on the stack anyway. @@ -336,18 +335,70 @@ struct fpreg fpreg; struct reg reg; } r; + void *addr; + int error = 0; + + addr = &r; + switch (uap->req) { + case PT_GETREGS: + case PT_GETFPREGS: + case PT_GETDBREGS: + break; + case PT_SETREGS: + error = copyin(uap->addr, &r.reg, sizeof r.reg); + break; + case PT_SETFPREGS: + error = copyin(uap->addr, &r.fpreg, sizeof r.fpreg); + break; + case PT_SETDBREGS: + error = copyin(uap->addr, &r.dbreg, sizeof r.dbreg); + break; + case PT_IO: + error = copyin(uap->addr, &r.piod, sizeof r.piod); + break; + default: + addr = uap->addr; + } + if (error) + return (error); + + error = kern_ptrace(td, uap->req, uap->pid, addr, uap->data); + if (error) + return (error); + + switch (uap->req) { + case PT_IO: + (void)copyout(&r.piod, uap->addr, sizeof r.piod); + break; + case PT_GETREGS: + error = copyout(&r.reg, uap->addr, sizeof r.reg); + break; + case PT_GETFPREGS: + error = copyout(&r.fpreg, uap->addr, sizeof r.fpreg); + break; + case PT_GETDBREGS: + error = copyout(&r.dbreg, uap->addr, sizeof r.dbreg); + break; + } + + return (error); +} + +int +kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) +{ + struct iovec iov; + struct uio uio; struct proc *curp, *p, *pp; struct thread *td2; + struct ptrace_io_desc *piod; int error, write, tmp; int proctree_locked = 0; curp = td->td_proc; - /* - * Do copyin() early before getting locks and lock proctree before - * locking the process. - */ - switch (uap->req) { + /* Lock proctree before locking the process. */ + switch (req) { case PT_TRACE_ME: case PT_ATTACH: case PT_STEP: @@ -356,37 +407,16 @@ sx_xlock(&proctree_lock); proctree_locked = 1; break; -#ifdef PT_SETREGS - case PT_SETREGS: - error = copyin(uap->addr, &r.reg, sizeof r.reg); - if (error) - return (error); - break; -#endif /* PT_SETREGS */ -#ifdef PT_SETFPREGS - case PT_SETFPREGS: - error = copyin(uap->addr, &r.fpreg, sizeof r.fpreg); - if (error) - return (error); - break; -#endif /* PT_SETFPREGS */ -#ifdef PT_SETDBREGS - case PT_SETDBREGS: - error = copyin(uap->addr, &r.dbreg, sizeof r.dbreg); - if (error) - return (error); - break; -#endif /* PT_SETDBREGS */ default: break; } write = 0; - if (uap->req == PT_TRACE_ME) { + if (req == PT_TRACE_ME) { p = td->td_proc; PROC_LOCK(p); } else { - if ((p = pfind(uap->pid)) == NULL) { + if ((p = pfind(pid)) == NULL) { if (proctree_locked) sx_xunlock(&proctree_lock); return (ESRCH); @@ -409,7 +439,7 @@ /* * Permissions check */ - switch (uap->req) { + switch (req) { case PT_TRACE_ME: /* Always legal. */ break; @@ -496,7 +526,7 @@ td->td_retval[0] = 0; - switch (uap->req) { + switch (req) { case PT_TRACE_ME: /* set my trace flag and "owner" so it can read/write me */ p->p_flag |= P_TRACED; @@ -511,21 +541,21 @@ p->p_oppid = p->p_pptr->p_pid; if (p->p_pptr != td->td_proc) proc_reparent(p, td->td_proc); - uap->data = SIGSTOP; + data = SIGSTOP; goto sendsig; /* in PT_CONTINUE below */ case PT_STEP: case PT_CONTINUE: case PT_DETACH: - /* XXX uap->data is used even in the PT_STEP case. */ - if (uap->req != PT_STEP && (unsigned)uap->data > _SIG_MAXSIG) { + /* XXX data is used even in the PT_STEP case. */ + if (req != PT_STEP && (unsigned)data > _SIG_MAXSIG) { error = EINVAL; goto fail; } _PHOLD(p); - if (uap->req == PT_STEP) { + if (req == PT_STEP) { error = ptrace_single_step(td2); if (error) { _PRELE(p); @@ -533,10 +563,9 @@ } } - if (uap->addr != (caddr_t)1) { + if (addr != (void *)1) { fill_kinfo_proc(p, &p->p_uarea->u_kproc); - error = ptrace_set_pc(td2, - (u_long)(uintfptr_t)uap->addr); + error = ptrace_set_pc(td2, (u_long)(uintfptr_t)addr); if (error) { _PRELE(p); goto fail; @@ -544,7 +573,7 @@ } _PRELE(p); - if (uap->req == PT_DETACH) { + if (req == PT_DETACH) { /* reset process parent */ if (p->p_oppid != p->p_pptr->p_pid) { struct proc *pp; @@ -569,14 +598,14 @@ sx_xunlock(&proctree_lock); /* deliver or queue signal */ if (P_SHOULDSTOP(p)) { - p->p_xstat = uap->data; + p->p_xstat = data; mtx_lock_spin(&sched_lock); p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SGNL); setrunnable(td2); /* XXXKSE */ /* Need foreach kse in proc, ... make_kse_queued(). */ mtx_unlock_spin(&sched_lock); - } else if (uap->data) - psignal(p, uap->data); + } else if (data) + psignal(p, data); PROC_UNLOCK(p); return (0); @@ -590,11 +619,11 @@ PROC_UNLOCK(p); tmp = 0; /* write = 0 set above */ - iov.iov_base = write ? (caddr_t)&uap->data : (caddr_t)&tmp; + iov.iov_base = write ? (caddr_t)&data : (caddr_t)&tmp; iov.iov_len = sizeof(int); uio.uio_iov = &iov; uio.uio_iovcnt = 1; - uio.uio_offset = (off_t)(uintptr_t)uap->addr; + uio.uio_offset = (off_t)(uintptr_t)addr; uio.uio_resid = sizeof(int); uio.uio_segflg = UIO_SYSSPACE; /* i.e.: the uap */ uio.uio_rw = write ? UIO_WRITE : UIO_READ; @@ -618,18 +647,16 @@ return (error); case PT_IO: - error = copyin(uap->addr, &r.piod, sizeof r.piod); - if (error) - return (error); - iov.iov_base = r.piod.piod_addr; - iov.iov_len = r.piod.piod_len; + piod = addr; + iov.iov_base = piod->piod_addr; + iov.iov_len = piod->piod_len; uio.uio_iov = &iov; uio.uio_iovcnt = 1; - uio.uio_offset = (off_t)(uintptr_t)r.piod.piod_offs; - uio.uio_resid = r.piod.piod_len; + uio.uio_offset = (off_t)(uintptr_t)piod->piod_offs; + uio.uio_resid = piod->piod_len; uio.uio_segflg = UIO_USERSPACE; uio.uio_td = td; - switch (r.piod.piod_op) { + switch (piod->piod_op) { case PIOD_READ_D: case PIOD_READ_I: uio.uio_rw = UIO_READ; @@ -642,60 +669,53 @@ return (EINVAL); } error = proc_rwmem(p, &uio); - r.piod.piod_len -= uio.uio_resid; - (void)copyout(&r.piod, uap->addr, sizeof r.piod); + piod->piod_len -= uio.uio_resid; return (error); case PT_KILL: - uap->data = SIGKILL; + data = SIGKILL; goto sendsig; /* in PT_CONTINUE above */ case PT_SETREGS: _PHOLD(p); - error = proc_write_regs(td2, &r.reg); + error = proc_write_regs(td2, addr); _PRELE(p); PROC_UNLOCK(p); return (error); case PT_GETREGS: _PHOLD(p); - error = proc_read_regs(td2, &r.reg); + error = proc_read_regs(td2, addr); _PRELE(p); PROC_UNLOCK(p); - if (error == 0) - error = copyout(&r.reg, uap->addr, sizeof r.reg); return (error); case PT_SETFPREGS: _PHOLD(p); - error = proc_write_fpregs(td2, &r.fpreg); + error = proc_write_fpregs(td2, addr); _PRELE(p); PROC_UNLOCK(p); return (error); case PT_GETFPREGS: _PHOLD(p); - error = proc_read_fpregs(td2, &r.fpreg); + error = proc_read_fpregs(td2, addr); _PRELE(p); PROC_UNLOCK(p); - if (error == 0) - error = copyout(&r.fpreg, uap->addr, sizeof r.fpreg); return (error); case PT_SETDBREGS: _PHOLD(p); - error = proc_write_dbregs(td2, &r.dbreg); + error = proc_write_dbregs(td2, addr); _PRELE(p); PROC_UNLOCK(p); return (error); case PT_GETDBREGS: _PHOLD(p); - error = proc_read_dbregs(td2, &r.dbreg); + error = proc_read_dbregs(td2, addr); _PRELE(p); PROC_UNLOCK(p); - if (error == 0) - error = copyout(&r.dbreg, uap->addr, sizeof r.dbreg); return (error); default: Index: sys/kern/sysv_sem.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/sysv_sem.c,v retrieving revision 1.55 diff -u -r1.55 sysv_sem.c --- sys/kern/sysv_sem.c 13 Aug 2002 08:47:17 -0000 1.55 +++ sys/kern/sysv_sem.c 1 Sep 2002 16:44:21 -0000 @@ -493,21 +493,69 @@ struct thread *td; struct __semctl_args *uap; { - int semid = uap->semid; - int semnum = uap->semnum; - int cmd = uap->cmd; + union semun user_arg, sys_arg, *arg; + struct semid_ds sbuf; + int error; + + switch (uap->cmd) { + case SEM_STAT: + case IPC_SET: + case IPC_STAT: + case GETALL: + case SETVAL: + case SETALL: + if ((error = copyin(uap->arg, &user_arg, + sizeof(user_arg))) != 0) + return (error); + switch (uap->cmd) { + case IPC_SET: + if ((error = copyin(user_arg.buf, &sbuf, + sizeof(sbuf))) != 0) + return (error); + /* FALLTHROUGH */ + case SEM_STAT: + case IPC_STAT: + sys_arg.buf = &sbuf; + arg = &sys_arg; + break; + case SETALL: /* XXX, we still use the user argument */ + case GETALL: + default: + arg = &user_arg; + break; + } + break; + default: + arg = NULL; + break; + } + + error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, arg); + if (error) + return (error); + + switch (uap->cmd) { + case IPC_STAT: + case SEM_STAT: + error = copyout(&sbuf, user_arg.buf, sizeof(struct semid_ds)); + break; + } + + return (error); +} + +int +kern_semctl(struct thread *td, int semid, int semnum, int cmd, union semun *arg) +{ u_short *array; - union semun *arg = uap->arg; - union semun real_arg; struct ucred *cred = td->td_ucred; - int i, rval, error; - struct semid_ds sbuf; + int i, ipcid, rval, error; struct semid_ds *semaptr; struct mtx *sema_mtxp; u_short usval, count; - DPRINTF(("call to semctl(%d, %d, %d, 0x%x)\n", - semid, semnum, cmd, arg)); + DPRINTF(("call to semctl(%d, %d, %d, %p)\n", + semid, semnum, cmd, (void *)arg)); if (!jail_sysvipc_allowed && jailed(td->td_ucred)) return (ENOSYS); @@ -517,8 +565,6 @@ case SEM_STAT: if (semid < 0 || semid >= seminfo.semmni) return (EINVAL); - if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - return (error); semaptr = &sema[semid]; sema_mtxp = &sema_mtx[semid]; mtx_lock(sema_mtxp); @@ -528,14 +574,13 @@ } if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) goto done2; + *arg->buf = *semaptr; + td->td_retval[0] = IXSEQ_TO_IPCID(semid, semaptr->sem_perm); mtx_unlock(sema_mtxp); - error = copyout(semaptr, real_arg.buf, sizeof(struct semid_ds)); - rval = IXSEQ_TO_IPCID(semid,semaptr->sem_perm); - if (error == 0) - td->td_retval[0] = rval; - return (error); + return (0); } + ipcid = semid; semid = IPCID_TO_IX(semid); if (semid < 0 || semid >= seminfo.semmni) return (EINVAL); @@ -549,7 +594,7 @@ switch (cmd) { case IPC_RMID: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; if ((error = ipcperm(td, &semaptr->sem_perm, IPC_M))) goto done2; @@ -571,39 +616,31 @@ break; case IPC_SET: - if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - goto done2; - if ((error = copyin(real_arg.buf, &sbuf, sizeof(sbuf))) != 0) - goto done2; mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; if ((error = ipcperm(td, &semaptr->sem_perm, IPC_M))) goto done2; - semaptr->sem_perm.uid = sbuf.sem_perm.uid; - semaptr->sem_perm.gid = sbuf.sem_perm.gid; + semaptr->sem_perm.uid = arg->buf->sem_perm.uid; + semaptr->sem_perm.gid = arg->buf->sem_perm.gid; semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) | - (sbuf.sem_perm.mode & 0777); + (arg->buf->sem_perm.mode & 0777); semaptr->sem_ctime = time_second; break; case IPC_STAT: - if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - goto done2; mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) goto done2; - sbuf = *semaptr; + *arg->buf = *semaptr; mtx_unlock(sema_mtxp); - error = copyout(semaptr, real_arg.buf, - sizeof(struct semid_ds)); break; case GETNCNT: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) goto done2; @@ -616,7 +653,7 @@ case GETPID: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) goto done2; @@ -629,7 +666,7 @@ case GETVAL: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) goto done2; @@ -641,25 +678,22 @@ break; case GETALL: - if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - goto done2; array = malloc(sizeof(*array) * semaptr->sem_nsems, M_TEMP, M_WAITOK); mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) goto done2; for (i = 0; i < semaptr->sem_nsems; i++) array[i] = semaptr->sem_base[i].semval; mtx_unlock(sema_mtxp); - error = copyout(array, real_arg.array, - i * sizeof(real_arg.array[0])); + error = copyout(array, arg->array, i * sizeof(arg->array[0])); break; case GETZCNT: mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R))) goto done2; @@ -671,10 +705,8 @@ break; case SETVAL: - if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - goto done2; mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; if ((error = ipcperm(td, &semaptr->sem_perm, IPC_W))) goto done2; @@ -682,11 +714,11 @@ error = EINVAL; goto done2; } - if (real_arg.val < 0 || real_arg.val > seminfo.semvmx) { + if (arg->val < 0 || arg->val > seminfo.semvmx) { error = ERANGE; goto done2; } - semaptr->sem_base[semnum].semval = real_arg.val; + semaptr->sem_base[semnum].semval = arg->val; SEMUNDO_LOCK(); semundo_clear(semid, semnum); SEMUNDO_UNLOCK(); @@ -696,18 +728,16 @@ case SETALL: mtx_lock(sema_mtxp); raced: - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; count = semaptr->sem_nsems; mtx_unlock(sema_mtxp); - if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0) - goto done2; array = malloc(sizeof(*array) * count, M_TEMP, M_WAITOK); - copyin(real_arg.array, array, count * sizeof(*array)); + copyin(arg->array, array, count * sizeof(*array)); if (error) break; mtx_lock(sema_mtxp); - if ((error = semvalid(uap->semid, semaptr)) != 0) + if ((error = semvalid(ipcid, semaptr)) != 0) goto done2; /* we could have raced? */ if (count != semaptr->sem_nsems) { Index: sys/kern/sysv_shm.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/sysv_shm.c,v retrieving revision 1.74 diff -u -r1.74 sysv_shm.c --- sys/kern/sysv_shm.c 15 Aug 2002 02:10:12 -0000 1.74 +++ sys/kern/sysv_shm.c 1 Sep 2002 16:44:21 -0000 @@ -476,78 +476,99 @@ struct thread *td; struct shmctl_args *uap; { + struct shmid_ds buf; + int error; + + switch (uap->cmd) { + case IPC_SET: + error = copyin(uap->buf, &buf, sizeof(buf)); + if (error) + return (error); + break; + case IPC_STAT: + case IPC_RMID: + break; + default: + return (EINVAL); + } + + error = kern_shmctl(td, uap->shmid, uap->cmd, &buf); + if (error) + return (error); + + switch (uap->cmd) { + case IPC_STAT: + error = copyout(&buf, uap->buf, sizeof(buf)); + break; + } + + return (error); +} + +int +kern_shmctl(struct thread *td, int shmid, int cmd, struct shmid_ds *buf) +{ int error = 0; - struct shmid_ds inbuf; struct shmid_ds *shmseg; + struct shm_info *shm_info; if (!jail_sysvipc_allowed && jailed(td->td_ucred)) return (ENOSYS); + mtx_lock(&Giant); - switch (uap->cmd) { - case IPC_INFO: - error = copyout(&shminfo, uap->buf, sizeof(shminfo)); - if (error) - goto done2; + switch (cmd) { + case IPC_INFO: /* XXX, gross, used only by linux emulation */ + bcopy(&shminfo, buf, sizeof(shminfo)); td->td_retval[0] = shmalloced; goto done2; - case SHM_INFO: { - struct shm_info shm_info; - shm_info.used_ids = shm_nused; - shm_info.shm_rss = 0; /*XXX where to get from ? */ - shm_info.shm_tot = 0; /*XXX where to get from ? */ - shm_info.shm_swp = 0; /*XXX where to get from ? */ - shm_info.swap_attempts = 0; /*XXX where to get from ? */ - shm_info.swap_successes = 0; /*XXX where to get from ? */ - error = copyout(&shm_info, uap->buf, sizeof(shm_info)); - if (error) - goto done2; + case SHM_INFO: /* XXX, gross, used only by linux emulation */ + shm_info = (struct shm_info *)buf; + shm_info->used_ids = shm_nused; + shm_info->shm_rss = 0; /*XXX where to get from ? */ + shm_info->shm_tot = 0; /*XXX where to get from ? */ + shm_info->shm_swp = 0; /*XXX where to get from ? */ + shm_info->swap_attempts = 0; /*XXX where to get from ? */ + shm_info->swap_successes = 0; /*XXX where to get from ? */ td->td_retval[0] = shmalloced; goto done2; } - } - if( (uap->cmd) == SHM_STAT ) - shmseg = shm_find_segment_by_shmidx(uap->shmid); + if (cmd == SHM_STAT) + shmseg = shm_find_segment_by_shmidx(shmid); else - shmseg = shm_find_segment_by_shmid(uap->shmid); + shmseg = shm_find_segment_by_shmid(shmid); if (shmseg == NULL) { error = EINVAL; goto done2; } - switch (uap->cmd) { - case SHM_STAT: + switch (cmd) { + case SHM_STAT: /* XXX, used only by linux emulation */ + td->td_retval[0] = IXSEQ_TO_IPCID(shmid, shmseg->shm_perm); + /* FALLTHROUGH */ case IPC_STAT: error = ipcperm(td, &shmseg->shm_perm, IPC_R); if (error) - goto done2; - error = copyout(shmseg, uap->buf, sizeof(inbuf)); - if (error) - goto done2; - else if( (uap->cmd) == SHM_STAT ) - td->td_retval[0] = IXSEQ_TO_IPCID( uap->shmid, shmseg->shm_perm ); + break; + *buf = *shmseg; break; case IPC_SET: error = ipcperm(td, &shmseg->shm_perm, IPC_M); if (error) - goto done2; - error = copyin(uap->buf, &inbuf, sizeof(inbuf)); - if (error) - goto done2; - shmseg->shm_perm.uid = inbuf.shm_perm.uid; - shmseg->shm_perm.gid = inbuf.shm_perm.gid; - shmseg->shm_perm.mode = - (shmseg->shm_perm.mode & ~ACCESSPERMS) | - (inbuf.shm_perm.mode & ACCESSPERMS); + break; + shmseg->shm_perm.uid = buf->shm_perm.uid; + shmseg->shm_perm.gid = buf->shm_perm.gid; + shmseg->shm_perm.mode = (shmseg->shm_perm.mode & ~ACCESSPERMS) | + (buf->shm_perm.mode & ACCESSPERMS); shmseg->shm_ctime = time_second; break; case IPC_RMID: error = ipcperm(td, &shmseg->shm_perm, IPC_M); if (error) - goto done2; + break; shmseg->shm_perm.key = IPC_PRIVATE; shmseg->shm_perm.mode |= SHMSEG_REMOVED; if (shmseg->shm_nattch <= 0) { shm_deallocate_segment(shmseg); - shm_last_free = IPCID_TO_IX(uap->shmid); + shm_last_free = IPCID_TO_IX(shmid); } break; #if 0 Index: sys/kern/uipc_socket.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/uipc_socket.c,v retrieving revision 1.131 diff -u -r1.131 uipc_socket.c --- sys/kern/uipc_socket.c 16 Aug 2002 12:51:58 -0000 1.131 +++ sys/kern/uipc_socket.c 1 Sep 2002 16:44:21 -0000 @@ -1239,7 +1239,7 @@ if (valsize > len) sopt->sopt_valsize = valsize = len; - if (sopt->sopt_td != 0) + if (sopt->sopt_segflg == SOPT_USERSPACE) return (copyin(sopt->sopt_val, buf, valsize)); bcopy(sopt->sopt_val, buf, valsize); @@ -1433,7 +1433,7 @@ valsize = min(len, sopt->sopt_valsize); sopt->sopt_valsize = valsize; if (sopt->sopt_val != 0) { - if (sopt->sopt_td != 0) + if (sopt->sopt_segflg == SOPT_USERSPACE) error = copyout(buf, sopt->sopt_val, valsize); else bcopy(buf, sopt->sopt_val, valsize); @@ -1622,7 +1622,7 @@ if (sopt->sopt_val == NULL) return 0; while (m != NULL && sopt->sopt_valsize >= m->m_len) { - if (sopt->sopt_td != NULL) { + if (sopt->sopt_segflg == SOPT_USERSPACE) { int error; error = copyin(sopt->sopt_val, mtod(m, char *), @@ -1652,7 +1652,7 @@ if (sopt->sopt_val == NULL) return 0; while (m != NULL && sopt->sopt_valsize >= m->m_len) { - if (sopt->sopt_td != NULL) { + if (sopt->sopt_segflg == SOPT_USERSPACE) { int error; error = copyout(mtod(m, char *), sopt->sopt_val, Index: sys/kern/uipc_syscalls.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.130 diff -u -r1.130 uipc_syscalls.c --- sys/kern/uipc_syscalls.c 28 Aug 2002 20:56:01 -0000 1.130 +++ sys/kern/uipc_syscalls.c 1 Sep 2002 16:44:21 -0000 @@ -1267,6 +1267,7 @@ sopt.sopt_val = uap->val; sopt.sopt_valsize = uap->valsize; sopt.sopt_td = td; + sopt.sopt_segflg = SOPT_USERSPACE; error = sosetopt(so, &sopt); fputsock(so); } @@ -1314,6 +1315,7 @@ sopt.sopt_val = uap->val; sopt.sopt_valsize = (size_t)valsize; /* checked non-negative above */ sopt.sopt_td = td; + sopt.sopt_segflg = SOPT_USERSPACE; error = sogetopt(so, &sopt); if (error == 0) { Index: sys/kern/vfs_cache.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/vfs_cache.c,v retrieving revision 1.75 diff -u -r1.75 vfs_cache.c --- sys/kern/vfs_cache.c 5 Aug 2002 08:55:53 -0000 1.75 +++ sys/kern/vfs_cache.c 1 Sep 2002 16:44:22 -0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -707,7 +708,14 @@ struct thread *td; struct __getcwd_args *uap; { - char *bp, *buf; + + return (kern___getcwd(td, uap->buf, UIO_USERSPACE, uap->buflen)); +} + +int +kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen) +{ + char *bp, *tmpbuf; int error, i, slash_prefixed; struct filedesc *fdp; struct namecache *ncp; @@ -716,12 +724,13 @@ numcwdcalls++; if (disablecwd) return (ENODEV); - if (uap->buflen < 2) + if (buflen < 2) return (EINVAL); - if (uap->buflen > MAXPATHLEN) - uap->buflen = MAXPATHLEN; - buf = bp = malloc(uap->buflen, M_TEMP, M_WAITOK); - bp += uap->buflen - 1; + if (buflen > MAXPATHLEN) + buflen = MAXPATHLEN; + error = 0; + tmpbuf = bp = malloc(buflen, M_TEMP, M_WAITOK); + bp += buflen - 1; *bp = '\0'; fdp = td->td_proc->p_fd; slash_prefixed = 0; @@ -731,7 +740,7 @@ if (vp->v_vflag & VV_ROOT) { if (vp->v_mount == NULL) { /* forced unmount */ FILEDESC_UNLOCK(fdp); - free(buf, M_TEMP); + free(tmpbuf, M_TEMP); return (EBADF); } vp = vp->v_mount->mnt_vnodecovered; @@ -740,35 +749,35 @@ if (vp->v_dd->v_id != vp->v_ddid) { FILEDESC_UNLOCK(fdp); numcwdfail1++; - free(buf, M_TEMP); + free(tmpbuf, M_TEMP); return (ENOTDIR); } ncp = TAILQ_FIRST(&vp->v_cache_dst); if (!ncp) { FILEDESC_UNLOCK(fdp); numcwdfail2++; - free(buf, M_TEMP); + free(tmpbuf, M_TEMP); return (ENOENT); } if (ncp->nc_dvp != vp->v_dd) { FILEDESC_UNLOCK(fdp); numcwdfail3++; - free(buf, M_TEMP); + free(tmpbuf, M_TEMP); return (EBADF); } for (i = ncp->nc_nlen - 1; i >= 0; i--) { - if (bp == buf) { + if (bp == tmpbuf) { FILEDESC_UNLOCK(fdp); numcwdfail4++; - free(buf, M_TEMP); + free(tmpbuf, M_TEMP); return (ENOMEM); } *--bp = ncp->nc_name[i]; } - if (bp == buf) { + if (bp == tmpbuf) { FILEDESC_UNLOCK(fdp); numcwdfail4++; - free(buf, M_TEMP); + free(tmpbuf, M_TEMP); return (ENOMEM); } *--bp = '/'; @@ -777,16 +786,19 @@ } FILEDESC_UNLOCK(fdp); if (!slash_prefixed) { - if (bp == buf) { + if (bp == tmpbuf) { numcwdfail4++; - free(buf, M_TEMP); + free(tmpbuf, M_TEMP); return (ENOMEM); } *--bp = '/'; } numcwdfound++; - error = copyout(bp, uap->buf, strlen(bp) + 1); - free(buf, M_TEMP); + if (bufseg == UIO_SYSSPACE) + bcopy(bp, buf, strlen(bp) + 1); + else + error = copyout(bp, buf, strlen(bp) + 1); + free(tmpbuf, M_TEMP); return (error); } Index: sys/kern/vfs_syscalls.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.284 diff -u -r1.284 vfs_syscalls.c --- sys/kern/vfs_syscalls.c 21 Aug 2002 03:55:35 -0000 1.284 +++ sys/kern/vfs_syscalls.c 1 Sep 2002 16:44:22 -0000 @@ -67,6 +67,7 @@ #include #include #include +#include #include #include @@ -79,7 +80,7 @@ static int change_dir(struct nameidata *ndp, struct thread *td); static int chroot_refuse_vdir_fds(struct filedesc *fdp); -static int getutimes(const struct timeval *, struct timespec *); +static int getutimes(const struct timeval *, enum uio_seg, struct timespec *); static int setfown(struct thread *td, struct vnode *, uid_t, gid_t); static int setfmode(struct thread *td, struct vnode *, int); static int setfflags(struct thread *td, struct vnode *, int); @@ -442,13 +443,19 @@ syscallarg(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; - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, - SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, pathseg, path, td); if ((error = change_dir(&nd, td)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -608,30 +615,38 @@ syscallarg(int) mode; } */ *uap; { + + return (kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode)); +} + +int +kern_open(struct thread *td, 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; struct vattr vat; struct mount *mp; - int cmode, flags, oflags; + int cmode, oflags; struct file *nfp; int type, indx, error; struct flock lf; struct nameidata nd; - oflags = SCARG(uap, flags); - if ((oflags & O_ACCMODE) == O_ACCMODE) + if ((flags & O_ACCMODE) == O_ACCMODE) return (EINVAL); - flags = FFLAGS(oflags); + oflags = flags; + flags = FFLAGS(flags); error = falloc(td, &nfp, &indx); if (error) return (error); fp = nfp; FILEDESC_LOCK(fdp); - cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; + cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; FILEDESC_UNLOCK(fdp); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); td->td_dupfd = -indx - 1; /* XXX check for fdopen */ /* * Bump the ref count to prevent another process from closing @@ -812,6 +827,14 @@ syscallarg(int) dev; } */ *uap; { + + return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); +} + +int +kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode, + int dev) +{ struct vnode *vp; struct mount *mp; struct vattr vattr; @@ -819,7 +842,7 @@ int whiteout = 0; struct nameidata nd; - switch (SCARG(uap, mode) & S_IFMT) { + switch (mode & S_IFMT) { case S_IFCHR: case S_IFBLK: error = suser(td); @@ -832,8 +855,7 @@ return (error); restart: bwillwrite(); - NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME, UIO_USERSPACE, - SCARG(uap, path), td); + NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; @@ -843,12 +865,13 @@ } else { VATTR_NULL(&vattr); FILEDESC_LOCK(td->td_proc->p_fd); - vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ td->td_proc->p_fd->fd_cmask; + vattr.va_mode = (mode & ALLPERMS) & + ~td->td_proc->p_fd->fd_cmask; FILEDESC_UNLOCK(td->td_proc->p_fd); - vattr.va_rdev = SCARG(uap, dev); + vattr.va_rdev = dev; whiteout = 0; - switch (SCARG(uap, mode) & S_IFMT) { + switch (mode & S_IFMT) { case S_IFMT: /* used by badsect to flag bad sectors */ vattr.va_type = VBAD; break; @@ -910,6 +933,13 @@ syscallarg(int) mode; } */ *uap; { + + return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode)); +} + +int +kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode) +{ struct mount *mp; struct vattr vattr; int error; @@ -917,8 +947,7 @@ restart: bwillwrite(); - NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME, UIO_USERSPACE, - SCARG(uap, path), td); + NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); if (nd.ni_vp != NULL) { @@ -937,7 +966,7 @@ VATTR_NULL(&vattr); vattr.va_type = VFIFO; FILEDESC_LOCK(td->td_proc->p_fd); - vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ td->td_proc->p_fd->fd_cmask; + vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; FILEDESC_UNLOCK(td->td_proc->p_fd); VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); @@ -967,13 +996,20 @@ syscallarg(char *) link; } */ *uap; { + + return (kern_link(td, uap->path, uap->link, UIO_USERSPACE)); +} + +int +kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg) +{ struct vnode *vp; struct mount *mp; struct nameidata nd; int error; bwillwrite(); - NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, UIO_USERSPACE, SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, segflg, path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -986,8 +1022,7 @@ vrele(vp); return (error); } - NDINIT(&nd, CREATE, LOCKPARENT | NOOBJ | SAVENAME, UIO_USERSPACE, - SCARG(uap, link), td); + NDINIT(&nd, CREATE, LOCKPARENT | NOOBJ | SAVENAME, segflg, link, td); if ((error = namei(&nd)) == 0) { if (nd.ni_vp != NULL) { vrele(nd.ni_vp); @@ -1025,19 +1060,29 @@ syscallarg(char *) link; } */ *uap; { + + return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE)); +} + +int +kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg) +{ struct mount *mp; struct vattr vattr; - char *path; + char *syspath; int error; struct nameidata nd; - path = uma_zalloc(namei_zone, M_WAITOK); - if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0) - goto out; + if (segflg == UIO_SYSSPACE) { + syspath = path; + } else { + syspath = uma_zalloc(namei_zone, M_WAITOK); + if ((error = copyinstr(path, syspath, MAXPATHLEN, NULL)) != 0) + goto out; + } restart: bwillwrite(); - NDINIT(&nd, CREATE, LOCKPARENT | NOOBJ | SAVENAME, UIO_USERSPACE, - SCARG(uap, link), td); + NDINIT(&nd, CREATE, LOCKPARENT | NOOBJ | SAVENAME, segflg, link, td); if ((error = namei(&nd)) != 0) goto out; if (nd.ni_vp) { @@ -1059,7 +1104,7 @@ vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask; FILEDESC_UNLOCK(td->td_proc->p_fd); VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); - error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path); + error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); NDFREE(&nd, NDF_ONLY_PNBUF); if (error == 0) vput(nd.ni_vp); @@ -1068,7 +1113,8 @@ ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); out: - uma_zfree(namei_zone, path); + if (segflg != UIO_SYSSPACE) + uma_zfree(namei_zone, syspath); return (error); } @@ -1135,6 +1181,13 @@ syscallarg(char *) path; } */ *uap; { + + return (kern_unlink(td, SCARG(uap, path), UIO_USERSPACE)); +} + +int +kern_unlink(struct thread *td, char *path, enum uio_seg pathseg) +{ struct mount *mp; struct vnode *vp; int error; @@ -1142,8 +1195,7 @@ restart: bwillwrite(); - NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, UIO_USERSPACE, - SCARG(uap, path), td); + NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; @@ -1343,6 +1395,13 @@ syscallarg(int) flags; } */ *uap; { + + return (kern_access(td, uap->path, UIO_USERSPACE, uap->flags)); +} + +int +kern_access(struct thread *td, char *path, enum uio_seg pathseg, int flags) +{ struct ucred *cred, *tmpcred; register struct vnode *vp; int error; @@ -1362,13 +1421,12 @@ tmpcred->cr_uid = cred->cr_ruid; tmpcred->cr_groups[0] = cred->cr_rgid; td->td_ucred = tmpcred; - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, - SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, pathseg, path, td); if ((error = namei(&nd)) != 0) goto out1; vp = nd.ni_vp; - error = vn_access(vp, SCARG(uap, flags), tmpcred, td); + error = vn_access(vp, flags, tmpcred, td); NDFREE(&nd, NDF_ONLY_PNBUF); vput(vp); out1: @@ -1749,14 +1807,22 @@ syscallarg(int) count; } */ *uap; { + + return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf, + UIO_USERSPACE, uap->count)); +} + +int +kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, + enum uio_seg bufseg, int count) +{ register struct vnode *vp; struct iovec aiov; struct uio auio; int error; struct nameidata nd; - NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, - SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -1771,19 +1837,19 @@ if (vp->v_type != VLNK) error = EINVAL; else { - aiov.iov_base = SCARG(uap, buf); - aiov.iov_len = SCARG(uap, count); + 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 = UIO_USERSPACE; + auio.uio_segflg = bufseg; auio.uio_td = td; - auio.uio_resid = SCARG(uap, count); + auio.uio_resid = count; error = VOP_READLINK(vp, &auio, td->td_ucred); } vput(vp); - td->td_retval[0] = SCARG(uap, count) - auio.uio_resid; + td->td_retval[0] = count - auio.uio_resid; return (error); } @@ -1959,14 +2025,21 @@ syscallarg(int) mode; } */ *uap; { + + return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode)); +} + +int +kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode) +{ int error; struct nameidata nd; - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); - error = setfmode(td, nd.ni_vp, SCARG(uap, mode)); + error = setfmode(td, nd.ni_vp, mode); vrele(nd.ni_vp); return error; } @@ -2083,14 +2156,22 @@ syscallarg(int) gid; } */ *uap; { + + return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); +} + +int +kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, + int gid) +{ int error; struct nameidata nd; - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); - error = setfown(td, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); + error = setfown(td, nd.ni_vp, uid, gid); vrele(nd.ni_vp); return (error); } @@ -2115,14 +2196,22 @@ syscallarg(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) +{ int error; struct nameidata nd; - NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, NOFOLLOW, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); - error = setfown(td, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); + error = setfown(td, nd.ni_vp, uid, gid); vrele(nd.ni_vp); return (error); } @@ -2164,11 +2253,13 @@ * Common implementation code for utimes(), lutimes(), and futimes(). */ static int -getutimes(usrtvp, tsp) +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) { @@ -2176,10 +2267,16 @@ TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); tsp[1] = tsp[0]; } else { - if ((error = copyin(usrtvp, tv, sizeof (tv))) != 0) - return (error); - TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); - TIMEVAL_TO_TIMESPEC(&tv[1], &tsp[1]); + if (tvpseg == UIO_SYSSPACE) { + tvp = usrtvp; + } else { + if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0) + return (error); + tvp = tv; + } + + TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); + TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); } return 0; } @@ -2245,19 +2342,26 @@ syscallarg(struct timeval *) tptr; } */ *uap; { + + return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr, + UIO_USERSPACE)); +} + +int +kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, + struct timeval *tptr, enum uio_seg tptrseg) +{ struct timespec ts[2]; - struct timeval *usrtvp; int error; struct nameidata nd; - usrtvp = SCARG(uap, tptr); - if ((error = getutimes(usrtvp, ts)) != 0) + if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); - error = setutimes(td, nd.ni_vp, ts, 2, usrtvp == NULL); + error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); vrele(nd.ni_vp); return (error); } @@ -2280,19 +2384,26 @@ syscallarg(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]; - struct timeval *usrtvp; int error; struct nameidata nd; - usrtvp = SCARG(uap, tptr); - if ((error = getutimes(usrtvp, ts)) != 0) + if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); - NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, NOFOLLOW, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); - error = setutimes(td, nd.ni_vp, ts, 2, usrtvp == NULL); + error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); vrele(nd.ni_vp); return (error); } @@ -2315,17 +2426,23 @@ syscallarg(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; - struct timeval *usrtvp; int error; - usrtvp = SCARG(uap, tptr); - if ((error = getutimes(usrtvp, ts)) != 0) + if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); - if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0) + if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0) return (error); - error = setutimes(td, (struct vnode *)fp->f_data, ts, 2, usrtvp==NULL); + error = setutimes(td, (struct vnode *)fp->f_data, ts, 2, tptr == NULL); fdrop(fp, td); return (error); } @@ -2350,15 +2467,22 @@ syscallarg(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; - if (uap->length < 0) + if (length < 0) return(EINVAL); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); + NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; @@ -2378,7 +2502,7 @@ else if ((error = vn_writechk(vp)) == 0 && (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) { VATTR_NULL(&vattr); - vattr.va_size = SCARG(uap, length); + vattr.va_size = length; error = VOP_SETATTR(vp, &vattr, td->td_ucred, td); } vput(vp); @@ -2570,14 +2694,20 @@ syscallarg(char *) to; } */ *uap; { + + return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE)); +} + +int +kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) +{ struct mount *mp; struct vnode *tvp, *fvp, *tdvp; struct nameidata fromnd, tond; int error; bwillwrite(); - NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE, - SCARG(uap, from), td); + NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, pathseg, from, td); if ((error = namei(&fromnd)) != 0) return (error); fvp = fromnd.ni_vp; @@ -2587,8 +2717,8 @@ vrele(fvp); goto out1; } - NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | NOOBJ, - UIO_USERSPACE, SCARG(uap, to), td); + NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | + NOOBJ, pathseg, to, td); if (fromnd.ni_vp->v_type == VDIR) tond.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&tond)) != 0) { @@ -2681,15 +2811,11 @@ } */ *uap; { - return vn_mkdir(uap->path, uap->mode, UIO_USERSPACE, td); + return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode)); } int -vn_mkdir(path, mode, segflg, td) - char *path; - int mode; - enum uio_seg segflg; - struct thread *td; +kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode) { struct mount *mp; struct vnode *vp; @@ -2758,6 +2884,13 @@ syscallarg(char *) path; } */ *uap; { + + return (kern_rmdir(td, uap->path, UIO_USERSPACE)); +} + +int +kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg) +{ struct mount *mp; struct vnode *vp; int error; @@ -2765,8 +2898,7 @@ restart: bwillwrite(); - NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, - SCARG(uap, path), td); + NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; Index: sys/netgraph/ng_ksocket.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/netgraph/ng_ksocket.c,v retrieving revision 1.32 diff -u -r1.32 ng_ksocket.c --- sys/netgraph/ng_ksocket.c 22 Aug 2002 00:30:03 -0000 1.32 +++ sys/netgraph/ng_ksocket.c 1 Sep 2002 16:44:22 -0000 @@ -823,6 +823,7 @@ sopt.sopt_level = ksopt->level; sopt.sopt_name = ksopt->name; sopt.sopt_td = NULL; + sopt.sopt_segflg = SOPT_SYSSPACE; sopt.sopt_valsize = NG_KSOCKET_MAX_OPTLEN; ksopt = (struct ng_ksocket_sockopt *)resp->data; sopt.sopt_val = ksopt->value; @@ -857,6 +858,7 @@ sopt.sopt_val = ksopt->value; sopt.sopt_valsize = valsize; sopt.sopt_td = NULL; + sopt.sopt_segflg = SOPT_SYSSPACE; error = sosetopt(so, &sopt); break; } Index: sys/netinet/in.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/netinet/in.h,v retrieving revision 1.70 diff -u -r1.70 in.h --- sys/netinet/in.h 21 Aug 2002 16:19:59 -0000 1.70 +++ sys/netinet/in.h 1 Sep 2002 16:44:22 -0000 @@ -366,6 +366,7 @@ #define IP_RECVOPTS 5 /* bool; receive all IP opts w/dgram */ #define IP_RECVRETOPTS 6 /* bool; receive IP opts for response */ #define IP_RECVDSTADDR 7 /* bool; receive IP dst addr w/dgram */ +#define IP_SENDSRCADDR IP_RECVDSTADDR /* cmsg_type to set src addr */ #define IP_RETOPTS 8 /* ip_opts; set/get IP options */ #define IP_MULTICAST_IF 9 /* u_char; set/get IP multicast i/f */ #define IP_MULTICAST_TTL 10 /* u_char; set/get IP multicast ttl */ Index: sys/netinet/in_pcb.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/netinet/in_pcb.c,v retrieving revision 1.110 diff -u -r1.110 in_pcb.c --- sys/netinet/in_pcb.c 21 Aug 2002 11:57:04 -0000 1.110 +++ sys/netinet/in_pcb.c 1 Sep 2002 16:44:22 -0000 @@ -179,17 +179,52 @@ struct sockaddr *nam; struct thread *td; { - register struct socket *so = inp->inp_socket; + int error; + + if (inp->inp_lport != 0 || inp->inp_laddr.s_addr != INADDR_ANY) + return (EINVAL); + error = in_pcbbind_setup(inp, nam, &inp->inp_laddr.s_addr, + &inp->inp_lport, td); + if (error) + return (error); + if (in_pcbinshash(inp) != 0) { + inp->inp_laddr.s_addr = INADDR_ANY; + inp->inp_lport = 0; + return (EAGAIN); + } + return (0); +} + +/* + * Set up a bind operation on a PCB, performing port allocation + * as required, but do not actually modify the PCB. Callers can + * either complete the bind by setting inp_laddr/inp_lport and + * calling in_pcbinshash(), or they can just use the resulting + * port and address to authorise the sending of a once-off packet. + * + * On error, the values of *laddrp and *lportp are not changed. + */ +int +in_pcbbind_setup(inp, nam, laddrp, lportp, td) + struct inpcb *inp; + struct sockaddr *nam; + in_addr_t *laddrp; + u_short *lportp; + struct thread *td; +{ + struct socket *so = inp->inp_socket; unsigned short *lastport; struct sockaddr_in *sin; struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; + struct in_addr laddr; u_short lport = 0; int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); int error, prison = 0; if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */ return (EADDRNOTAVAIL); - if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) + laddr.s_addr = *laddrp; + if (nam != NULL && laddr.s_addr != INADDR_ANY) return (EINVAL); if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) wild = 1; @@ -208,7 +243,13 @@ if (sin->sin_addr.s_addr != INADDR_ANY) if (prison_ip(td->td_ucred, 0, &sin->sin_addr.s_addr)) return(EINVAL); - lport = sin->sin_port; + if (sin->sin_port != *lportp) { + /* Don't allow the port to change. */ + if (*lportp != 0) + return (EINVAL); + lport = sin->sin_port; + } + /* NB: lport is left as 0 if the port isn't being changed. */ if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { /* * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; @@ -225,6 +266,7 @@ if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) return (EADDRNOTAVAIL); } + laddr = sin->sin_addr; if (lport) { struct inpcb *t; /* GROSS */ @@ -274,17 +316,16 @@ return (EADDRINUSE); } } - inp->inp_laddr = sin->sin_addr; } + if (*lportp != 0) + lport = *lportp; if (lport == 0) { ushort first, last; int count; - if (inp->inp_laddr.s_addr != INADDR_ANY) - if (prison_ip(td->td_ucred, 0, &inp->inp_laddr.s_addr )) { - inp->inp_laddr.s_addr = INADDR_ANY; + if (laddr.s_addr != INADDR_ANY) + if (prison_ip(td->td_ucred, 0, &laddr.s_addr)) return (EINVAL); - } inp->inp_flags |= INP_ANONPORT; if (inp->inp_flags & INP_HIGHPORT) { @@ -292,10 +333,9 @@ last = ipport_hilastauto; lastport = &pcbinfo->lasthi; } else if (inp->inp_flags & INP_LOWPORT) { - if (td && (error = suser_cred(td->td_ucred, PRISON_ROOT))) { - inp->inp_laddr.s_addr = INADDR_ANY; + if (td && (error = suser_cred(td->td_ucred, + PRISON_ROOT))) return error; - } first = ipport_lowfirstauto; /* 1023 */ last = ipport_lowlastauto; /* 600 */ lastport = &pcbinfo->lastlow; @@ -318,16 +358,14 @@ count = first - last; do { - if (count-- < 0) { /* completely used? */ - inp->inp_laddr.s_addr = INADDR_ANY; + if (count-- < 0) /* completely used? */ return (EADDRNOTAVAIL); - } --*lastport; if (*lastport > first || *lastport < last) *lastport = first; lport = htons(*lastport); - } while (in_pcblookup_local(pcbinfo, - inp->inp_laddr, lport, wild)); + } while (in_pcblookup_local(pcbinfo, laddr, lport, + wild)); } else { /* * counting up @@ -335,63 +373,125 @@ count = last - first; do { - if (count-- < 0) { /* completely used? */ - /* - * Undo any address bind that may have - * occurred above. - */ - inp->inp_laddr.s_addr = INADDR_ANY; + if (count-- < 0) /* completely used? */ return (EADDRNOTAVAIL); - } ++*lastport; if (*lastport < first || *lastport > last) *lastport = first; lport = htons(*lastport); - } while (in_pcblookup_local(pcbinfo, - inp->inp_laddr, lport, wild)); + } while (in_pcblookup_local(pcbinfo, laddr, lport, + wild)); } } - inp->inp_lport = lport; - if (prison_ip(td->td_ucred, 0, &inp->inp_laddr.s_addr)) { - inp->inp_laddr.s_addr = INADDR_ANY; - inp->inp_lport = 0; + if (prison_ip(td->td_ucred, 0, &laddr.s_addr)) return (EINVAL); + *laddrp = laddr.s_addr; + *lportp = lport; + return (0); +} + +/* + * Connect from a socket to a specified address. + * Both address and port must be specified in argument sin. + * If don't have a local address for this socket yet, + * then pick one. + */ +int +in_pcbconnect(inp, nam, td) + register struct inpcb *inp; + struct sockaddr *nam; + struct thread *td; +{ + u_short lport, fport; + in_addr_t laddr, faddr; + int error; + + lport = inp->inp_lport; + laddr = inp->inp_laddr.s_addr; + error = in_pcbconnect_setup(inp, nam, &laddr, &lport, &faddr, &fport, + NULL, td); + if (error) + return (error); + + /* Do the initial binding of the local address if required. */ + if (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0) { + inp->inp_lport = lport; + inp->inp_laddr.s_addr = laddr; + if (in_pcbinshash(inp) != 0) { + inp->inp_laddr.s_addr = INADDR_ANY; + inp->inp_lport = 0; + return (EAGAIN); + } } - if (in_pcbinshash(inp) != 0) { - inp->inp_laddr.s_addr = INADDR_ANY; - inp->inp_lport = 0; - return (EAGAIN); - } + + /* Commit the remaining changes. */ + inp->inp_lport = lport; + inp->inp_laddr.s_addr = laddr; + inp->inp_faddr.s_addr = faddr; + inp->inp_fport = fport; + in_pcbrehash(inp); return (0); } /* - * Transform old in_pcbconnect() into an inner subroutine for new - * in_pcbconnect(): Do some validity-checking on the remote - * address (in mbuf 'nam') and then determine local host address - * (i.e., which interface) to use to access that remote host. + * Set up for a connect from a socket to the specified address. + * On entry, *laddrp and *lportp should contain the current local + * address and port for the PCB; these are updated to the values + * that should be placed in inp_laddr and inp_lport to complete + * the connect. + * + * On success, *fportp and *lportp will be set to the remote address + * and port. These are not updated in the error case. * - * This preserves definition of in_pcbconnect(), while supporting a - * slightly different version for T/TCP. (This is more than - * a bit of a kludge, but cleaning up the internal interfaces would - * have forced minor changes in every protocol). + * If the operation fails because the connection already exists, + * *oinpp will be set to the PCB of that connection so that the + * caller can decide to override it. In all other cases, *oinpp + * is set to NULL. */ - int -in_pcbladdr(inp, nam, plocal_sin) +in_pcbconnect_setup(inp, nam, laddrp, lportp, faddrp, fportp, oinpp, td) register struct inpcb *inp; struct sockaddr *nam; - struct sockaddr_in **plocal_sin; + in_addr_t *laddrp; + u_short *lportp; + in_addr_t *faddrp; + u_short *fportp; + struct inpcb **oinpp; + struct thread *td; { + struct sockaddr_in *sin = (struct sockaddr_in *)nam; struct in_ifaddr *ia; - register struct sockaddr_in *sin = (struct sockaddr_in *)nam; + struct sockaddr_in sa; + struct ucred *cred; + struct inpcb *oinp; + struct in_addr laddr, faddr; + u_short lport, fport; + int error; + if (oinpp != NULL) + *oinpp = NULL; if (nam->sa_len != sizeof (*sin)) return (EINVAL); if (sin->sin_family != AF_INET) return (EAFNOSUPPORT); if (sin->sin_port == 0) return (EADDRNOTAVAIL); + laddr.s_addr = *laddrp; + lport = *lportp; + faddr = sin->sin_addr; + fport = sin->sin_port; + cred = inp->inp_socket->so_cred; + if (laddr.s_addr == INADDR_ANY && jailed(cred)) { + bzero(&sa, sizeof(sa)); + sa.sin_addr.s_addr = htonl(prison_getip(cred)); + sa.sin_len = sizeof(sa); + sa.sin_family = AF_INET; + error = in_pcbbind_setup(inp, (struct sockaddr *)&sa, + &laddr.s_addr, &lport, td); + if (error) + return (error); + } + if (!TAILQ_EMPTY(&in_ifaddrhead)) { /* * If the destination address is INADDR_ANY, @@ -400,13 +500,15 @@ * and the primary interface supports broadcast, * choose the broadcast address for that interface. */ - if (sin->sin_addr.s_addr == INADDR_ANY) - sin->sin_addr = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr; - else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST && - (TAILQ_FIRST(&in_ifaddrhead)->ia_ifp->if_flags & IFF_BROADCAST)) - sin->sin_addr = satosin(&TAILQ_FIRST(&in_ifaddrhead)->ia_broadaddr)->sin_addr; + if (faddr.s_addr == INADDR_ANY) + faddr = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr; + else if (faddr.s_addr == (u_long)INADDR_BROADCAST && + (TAILQ_FIRST(&in_ifaddrhead)->ia_ifp->if_flags & + IFF_BROADCAST)) + faddr = satosin(&TAILQ_FIRST( + &in_ifaddrhead)->ia_broadaddr)->sin_addr; } - if (inp->inp_laddr.s_addr == INADDR_ANY) { + if (laddr.s_addr == INADDR_ANY) { register struct route *ro; ia = (struct in_ifaddr *)0; @@ -419,8 +521,7 @@ ro = &inp->inp_route; if (ro->ro_rt && (ro->ro_dst.sa_family != AF_INET || - satosin(&ro->ro_dst)->sin_addr.s_addr != - sin->sin_addr.s_addr || + satosin(&ro->ro_dst)->sin_addr.s_addr != faddr.s_addr || inp->inp_socket->so_options & SO_DONTROUTE)) { RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)0; @@ -432,8 +533,7 @@ bzero(&ro->ro_dst, sizeof(struct sockaddr_in)); ro->ro_dst.sa_family = AF_INET; ro->ro_dst.sa_len = sizeof(struct sockaddr_in); - ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = - sin->sin_addr; + ((struct sockaddr_in *)&ro->ro_dst)->sin_addr = faddr; rtalloc(ro); } /* @@ -445,13 +545,14 @@ if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) ia = ifatoia(ro->ro_rt->rt_ifa); if (ia == 0) { - u_short fport = sin->sin_port; + bzero(&sa, sizeof(sa)); + sa.sin_addr = faddr; + sa.sin_len = sizeof(sa); + sa.sin_family = AF_INET; - sin->sin_port = 0; - ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); + ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sa))); if (ia == 0) - ia = ifatoia(ifa_ifwithnet(sintosa(sin))); - sin->sin_port = fport; + ia = ifatoia(ifa_ifwithnet(sintosa(&sa))); if (ia == 0) ia = TAILQ_FIRST(&in_ifaddrhead); if (ia == 0) @@ -462,7 +563,7 @@ * interface has been set as a multicast option, use the * address of that interface as our source address. */ - if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && + if (IN_MULTICAST(ntohl(faddr.s_addr)) && inp->inp_moptions != NULL) { struct ip_moptions *imo; struct ifnet *ifp; @@ -477,67 +578,25 @@ return (EADDRNOTAVAIL); } } - /* - * Don't do pcblookup call here; return interface in plocal_sin - * and exit to caller, that will do the lookup. - */ - *plocal_sin = &ia->ia_addr; - + laddr = ia->ia_addr.sin_addr; } - return(0); -} - -/* - * Outer subroutine: - * Connect from a socket to a specified address. - * Both address and port must be specified in argument sin. - * If don't have a local address for this socket yet, - * then pick one. - */ -int -in_pcbconnect(inp, nam, td) - register struct inpcb *inp; - struct sockaddr *nam; - struct thread *td; -{ - struct sockaddr_in *ifaddr; - struct sockaddr_in *sin = (struct sockaddr_in *)nam; - struct sockaddr_in sa; - struct ucred *cred; - int error; - cred = inp->inp_socket->so_cred; - if (inp->inp_laddr.s_addr == INADDR_ANY && jailed(cred)) { - bzero(&sa, sizeof (sa)); - sa.sin_addr.s_addr = htonl(prison_getip(cred)); - sa.sin_len=sizeof (sa); - sa.sin_family = AF_INET; - error = in_pcbbind(inp, (struct sockaddr *)&sa, td); - if (error) - return (error); - } - /* - * Call inner routine, to assign local interface address. - */ - if ((error = in_pcbladdr(inp, nam, &ifaddr)) != 0) - return(error); - - if (in_pcblookup_hash(inp->inp_pcbinfo, sin->sin_addr, sin->sin_port, - inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr, - inp->inp_lport, 0, NULL) != NULL) { + oinp = in_pcblookup_hash(inp->inp_pcbinfo, faddr, fport, laddr, lport, + 0, NULL); + if (oinp != NULL) { + if (oinpp != NULL) + *oinpp = oinp; return (EADDRINUSE); } - if (inp->inp_laddr.s_addr == INADDR_ANY) { - if (inp->inp_lport == 0) { - error = in_pcbbind(inp, (struct sockaddr *)0, td); - if (error) - return (error); - } - inp->inp_laddr = ifaddr->sin_addr; + if (laddr.s_addr == INADDR_ANY || lport == 0) { + error = in_pcbbind_setup(inp, NULL, &laddr.s_addr, &lport, td); + if (error) + return (error); } - inp->inp_faddr = sin->sin_addr; - inp->inp_fport = sin->sin_port; - in_pcbrehash(inp); + *laddrp = laddr.s_addr; + *lportp = lport; + *faddrp = faddr.s_addr; + *fportp = fport; return (0); } Index: sys/netinet/in_pcb.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/netinet/in_pcb.h,v retrieving revision 1.52 diff -u -r1.52 in_pcb.h --- sys/netinet/in_pcb.h 21 Aug 2002 11:57:05 -0000 1.52 +++ sys/netinet/in_pcb.h 1 Sep 2002 16:44:22 -0000 @@ -327,12 +327,15 @@ in_rtchange(struct inpcb *, int); int in_pcballoc(struct socket *, struct inpcbinfo *, struct thread *); int in_pcbbind(struct inpcb *, struct sockaddr *, struct thread *); +int in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *, + u_short *, struct thread *); int in_pcbconnect(struct inpcb *, struct sockaddr *, struct thread *); +int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *, + u_short *, in_addr_t *, u_short *, struct inpcb **, + struct thread *); void in_pcbdetach(struct inpcb *); void in_pcbdisconnect(struct inpcb *); int in_pcbinshash(struct inpcb *); -int in_pcbladdr(struct inpcb *, struct sockaddr *, - struct sockaddr_in **); struct inpcb * in_pcblookup_local(struct inpcbinfo *, struct in_addr, u_int, int); Index: sys/netinet/tcp_usrreq.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.82 diff -u -r1.82 tcp_usrreq.c --- sys/netinet/tcp_usrreq.c 22 Aug 2002 21:24:01 -0000 1.82 +++ sys/netinet/tcp_usrreq.c 1 Sep 2002 16:44:22 -0000 @@ -832,10 +832,10 @@ /* * Common subroutine to open a TCP connection to remote host specified * by struct sockaddr_in in mbuf *nam. Call in_pcbbind to assign a local - * port number if needed. Call in_pcbladdr to do the routing and to choose - * a local host address (interface). If there is an existing incarnation - * of the same connection in TIME-WAIT state and if the remote host was - * sending CC options and if the connection duration was < MSL, then + * port number if needed. Call in_pcbconnect_setup to do the routing and + * to choose a local host address (interface). If there is an existing + * incarnation of the same connection in TIME-WAIT state and if the remote + * host was sending CC options and if the connection duration was < MSL, then * truncate the previous TIME-WAIT state and proceed. * Initialize connection parameters and enter SYN-SENT state. */ @@ -849,9 +849,10 @@ struct socket *so = inp->inp_socket; struct tcpcb *otp; struct sockaddr_in *sin = (struct sockaddr_in *)nam; - struct sockaddr_in *ifaddr; struct rmxp_tao *taop; struct rmxp_tao tao_noncached; + struct in_addr laddr; + u_short lport; int error; if (inp->inp_lport == 0) { @@ -860,19 +861,12 @@ return error; } - /* - * Cannot simply call in_pcbconnect, because there might be an - * earlier incarnation of this same connection still in - * TIME_WAIT state, creating an ADDRINUSE error. - */ - error = in_pcbladdr(inp, nam, &ifaddr); - if (error) + laddr = inp->inp_laddr; + lport = inp->inp_lport; + error = in_pcbconnect_setup(inp, nam, &laddr.s_addr, &lport, + &inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, td); + if (error && oinp == NULL) return error; - oinp = in_pcblookup_hash(inp->inp_pcbinfo, - sin->sin_addr, sin->sin_port, - inp->inp_laddr.s_addr != INADDR_ANY ? inp->inp_laddr - : ifaddr->sin_addr, - inp->inp_lport, 0, NULL); if (oinp) { if (oinp != inp && (otp = intotcpcb(oinp)) != NULL && otp->t_state == TCPS_TIME_WAIT && @@ -882,8 +876,7 @@ else return EADDRINUSE; } - if (inp->inp_laddr.s_addr == INADDR_ANY) - inp->inp_laddr = ifaddr->sin_addr; + inp->inp_laddr = laddr; inp->inp_faddr = sin->sin_addr; inp->inp_fport = sin->sin_port; in_pcbrehash(inp); Index: sys/netinet/udp_usrreq.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/netinet/udp_usrreq.c,v retrieving revision 1.122 diff -u -r1.122 udp_usrreq.c --- sys/netinet/udp_usrreq.c 15 Aug 2002 22:04:31 -0000 1.122 +++ sys/netinet/udp_usrreq.c 1 Sep 2002 16:44:22 -0000 @@ -34,6 +34,7 @@ * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.122 2002/08/15 22:04:31 rwatson Exp $ */ +#include "opt_ipfw.h" #include "opt_ipsec.h" #include "opt_inet6.h" #include "opt_mac.h" @@ -727,7 +728,7 @@ static int udp_output(inp, m, addr, control, td) - register struct inpcb *inp; + struct inpcb *inp; struct mbuf *m; struct sockaddr *addr; struct mbuf *control; @@ -735,42 +736,110 @@ { register struct udpiphdr *ui; register int len = m->m_pkthdr.len; - struct in_addr laddr; - struct sockaddr_in *sin; - int s = 0, error = 0; + struct in_addr faddr, laddr; + struct cmsghdr *cm = NULL; + struct sockaddr_in *sin, src; + int error = 0; + u_short fport, lport; #ifdef MAC mac_create_mbuf_from_socket(inp->inp_socket, m); #endif - if (control) - m_freem(control); /* XXX */ - if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) { error = EMSGSIZE; + if (control) + m_freem(control); + goto release; + } + + src.sin_addr.s_addr = INADDR_ANY; + if (control != NULL) { + /* + * XXX: Currently, we assume all the optional information + * is stored in a single mbuf. + */ + if (control->m_next) { + error = EINVAL; + m_freem(control); + goto release; + } + for (; control->m_len > 0; + control->m_data += CMSG_ALIGN(cm->cmsg_len), + control->m_len -= CMSG_ALIGN(cm->cmsg_len)) { + cm = mtod(control, struct cmsghdr *); + if (control->m_len < sizeof(*cm) || cm->cmsg_len == 0 || + cm->cmsg_len > control->m_len) { + error = EINVAL; + break; + } + if (cm->cmsg_level != IPPROTO_IP) + continue; + + switch (cm->cmsg_type) { + case IP_SENDSRCADDR: + if (cm->cmsg_len != + CMSG_LEN(sizeof(struct in_addr))) { + error = EINVAL; + break; + } + bzero(&src, sizeof(src)); + src.sin_family = AF_INET; + src.sin_len = sizeof(src); + src.sin_port = inp->inp_lport; + src.sin_addr = *(struct in_addr *)CMSG_DATA(cm); + break; + default: + error = ENOPROTOOPT; + break; + } + if (error) + break; + } + m_freem(control); + } + if (error) goto release; + laddr = inp->inp_laddr; + lport = inp->inp_lport; + if (src.sin_addr.s_addr != INADDR_ANY) { + if (lport == 0) { + error = EINVAL; + goto release; + } + error = in_pcbbind_setup(inp, (struct sockaddr *)&src, + &laddr.s_addr, &lport, td); + if (error) + goto release; } if (addr) { sin = (struct sockaddr_in *)addr; if (td && jailed(td->td_ucred)) prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr); - laddr = inp->inp_laddr; if (inp->inp_faddr.s_addr != INADDR_ANY) { error = EISCONN; goto release; } - /* - * Must block input while temporarily connected. - */ - s = splnet(); - error = in_pcbconnect(inp, addr, td); - if (error) { - splx(s); + error = in_pcbconnect_setup(inp, addr, &laddr.s_addr, &lport, + &faddr.s_addr, &fport, NULL, td); + if (error) goto release; + + /* Commit the local port if newly assigned. */ + if (inp->inp_laddr.s_addr == INADDR_ANY && + inp->inp_lport == 0) { + inp->inp_lport = lport; + if (in_pcbinshash(inp) != 0) { + inp->inp_lport = 0; + error = EAGAIN; + goto release; + } } } else { - if (inp->inp_faddr.s_addr == INADDR_ANY) { + faddr = inp->inp_faddr; + fport = inp->inp_fport; + if (faddr.s_addr == INADDR_ANY) { error = ENOTCONN; goto release; } @@ -782,8 +851,6 @@ M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); if (m == 0) { error = ENOBUFS; - if (addr) - splx(s); goto release; } @@ -794,10 +861,10 @@ ui = mtod(m, struct udpiphdr *); bzero(ui->ui_x1, sizeof(ui->ui_x1)); /* XXX still needed? */ ui->ui_pr = IPPROTO_UDP; - ui->ui_src = inp->inp_laddr; - ui->ui_dst = inp->inp_faddr; - ui->ui_sport = inp->inp_lport; - ui->ui_dport = inp->inp_fport; + ui->ui_src = laddr; + ui->ui_dst = faddr; + ui->ui_sport = lport; + ui->ui_dport = fport; ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr)); /* @@ -825,12 +892,6 @@ error = ip_output(m, inp->inp_options, &inp->inp_route, (inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST)), inp->inp_moptions); - - if (addr) { - in_pcbdisconnect(inp); - inp->inp_laddr = laddr; /* XXX rehash? */ - splx(s); - } return (error); release: Index: sys/netncp/ncp_conn.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/netncp/ncp_conn.c,v retrieving revision 1.19 diff -u -r1.19 ncp_conn.c --- sys/netncp/ncp_conn.c 28 Jul 2002 19:59:31 -0000 1.19 +++ sys/netncp/ncp_conn.c 1 Sep 2002 16:44:22 -0000 @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include Index: sys/netsmb/smb_trantcp.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/netsmb/smb_trantcp.c,v retrieving revision 1.12 diff -u -r1.12 smb_trantcp.c --- sys/netsmb/smb_trantcp.c 31 May 2002 11:52:34 -0000 1.12 +++ sys/netsmb/smb_trantcp.c 1 Sep 2002 16:44:22 -0000 @@ -90,6 +90,7 @@ sopt.sopt_name = name; sopt.sopt_val = &val; sopt.sopt_valsize = sizeof(val); + sopt.sopt_segflg = SOPT_SYSSPACE; return sosetopt(so, &sopt); } Index: sys/nfsclient/bootp_subr.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/nfsclient/bootp_subr.c,v retrieving revision 1.42 diff -u -r1.42 bootp_subr.c --- sys/nfsclient/bootp_subr.c 18 Aug 2002 07:04:59 -0000 1.42 +++ sys/nfsclient/bootp_subr.c 1 Sep 2002 16:44:22 -0000 @@ -605,6 +605,7 @@ sopt.sopt_name = SO_RCVTIMEO; sopt.sopt_val = &tv; sopt.sopt_valsize = sizeof tv; + sopt.sopt_segflg = SOPT_SYSSPACE; error = sosetopt(so, &sopt); if (error != 0) Index: sys/nfsclient/krpc_subr.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/nfsclient/krpc_subr.c,v retrieving revision 1.20 diff -u -r1.20 krpc_subr.c --- sys/nfsclient/krpc_subr.c 27 Feb 2002 18:32:19 -0000 1.20 +++ sys/nfsclient/krpc_subr.c 1 Sep 2002 16:44:22 -0000 @@ -226,6 +226,7 @@ sopt.sopt_name = SO_RCVTIMEO; sopt.sopt_val = &tv; sopt.sopt_valsize = sizeof tv; + sopt.sopt_segflg = SOPT_SYSSPACE; if ((error = sosetopt(so, &sopt)) != 0) goto out; Index: sys/nfsclient/nfs_socket.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/nfsclient/nfs_socket.c,v retrieving revision 1.85 diff -u -r1.85 nfs_socket.c --- sys/nfsclient/nfs_socket.c 16 Jul 2002 15:12:07 -0000 1.85 +++ sys/nfsclient/nfs_socket.c 1 Sep 2002 16:44:22 -0000 @@ -184,6 +184,7 @@ case AF_INET: sopt.sopt_level = IPPROTO_IP; sopt.sopt_name = IP_PORTRANGE; + sopt.sopt_segflg = SOPT_SYSSPACE; ip = IP_PORTRANGE_LOW; ip2 = IP_PORTRANGE_DEFAULT; len = sizeof (struct sockaddr_in); @@ -192,6 +193,7 @@ case AF_INET6: sopt.sopt_level = IPPROTO_IPV6; sopt.sopt_name = IPV6_PORTRANGE; + sopt.sopt_segflg = SOPT_SYSSPACE; ip = IPV6_PORTRANGE_LOW; ip2 = IPV6_PORTRANGE_DEFAULT; len = sizeof (struct sockaddr_in6); @@ -207,6 +209,7 @@ sopt.sopt_dir = SOPT_SET; sopt.sopt_val = (void *)&ip; sopt.sopt_valsize = sizeof(ip); + sopt.sopt_segflg = SOPT_SYSSPACE; error = sosetopt(so, &sopt); if (error) goto bad; @@ -292,6 +295,7 @@ sopt.sopt_name = SO_KEEPALIVE; sopt.sopt_val = &val; sopt.sopt_valsize = sizeof val; + sopt.sopt_segflg = SOPT_SYSSPACE; val = 1; sosetopt(so, &sopt); } @@ -304,6 +308,7 @@ sopt.sopt_name = TCP_NODELAY; sopt.sopt_val = &val; sopt.sopt_valsize = sizeof val; + sopt.sopt_segflg = SOPT_SYSSPACE; val = 1; sosetopt(so, &sopt); } Index: sys/nfsserver/nfs_syscalls.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/nfsserver/nfs_syscalls.c,v retrieving revision 1.80 diff -u -r1.80 nfs_syscalls.c --- sys/nfsserver/nfs_syscalls.c 24 Jul 2002 23:10:34 -0000 1.80 +++ sys/nfsserver/nfs_syscalls.c 1 Sep 2002 16:44:22 -0000 @@ -233,6 +233,7 @@ sopt.sopt_name = SO_KEEPALIVE; sopt.sopt_val = &val; sopt.sopt_valsize = sizeof val; + sopt.sopt_segflg = SOPT_SYSSPACE; val = 1; sosetopt(so, &sopt); } @@ -245,6 +246,7 @@ sopt.sopt_name = TCP_NODELAY; sopt.sopt_val = &val; sopt.sopt_valsize = sizeof val; + sopt.sopt_segflg = SOPT_SYSSPACE; val = 1; sosetopt(so, &sopt); } Index: sys/sys/sem.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/sys/sem.h,v retrieving revision 1.25 diff -u -r1.25 sem.h --- sys/sys/sem.h 19 Mar 2002 20:18:41 -0000 1.25 +++ sys/sys/sem.h 1 Sep 2002 16:44:22 -0000 @@ -92,6 +92,8 @@ * Process sem_undo vectors at proc exit. */ void semexit(struct proc *p); +int kern_semctl(struct thread *td, int semid, int semnum, int cmd, + union semun *arg); #endif /* _KERNEL */ #ifndef _KERNEL Index: sys/sys/shm.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/sys/shm.h,v retrieving revision 1.17 diff -u -r1.17 shm.h --- sys/sys/shm.h 19 Mar 2002 20:18:41 -0000 1.17 +++ sys/sys/shm.h 1 Sep 2002 16:44:22 -0000 @@ -100,6 +100,8 @@ void shmexit(struct proc *); void shmfork(struct proc *, struct proc *); +int kern_shmctl(struct thread *td, int shmid, int cmd, + struct shmid_ds *buf); #else /* !_KERNEL */ #include Index: sys/sys/socketvar.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/sys/socketvar.h,v retrieving revision 1.94 diff -u -r1.94 socketvar.h --- sys/sys/socketvar.h 17 Aug 2002 02:36:16 -0000 1.94 +++ sys/sys/socketvar.h 1 Sep 2002 16:44:22 -0000 @@ -296,12 +296,14 @@ * section because it will never be visible to user code. */ enum sopt_dir { SOPT_GET, SOPT_SET }; +enum sopt_seg { SOPT_USERSPACE, SOPT_SYSSPACE }; struct sockopt { enum sopt_dir sopt_dir; /* is this a get or a set? */ int sopt_level; /* second arg of [gs]etsockopt */ int sopt_name; /* third arg of [gs]etsockopt */ void *sopt_val; /* fourth arg of [gs]etsockopt */ size_t sopt_valsize; /* (almost) fifth arg of [gs]etsockopt */ + enum sopt_seg sopt_segflg; /* address space for sopt_val */ struct thread *sopt_td; /* calling thread or null if kernel */ }; Index: sys/sys/syscallsubr.h =================================================================== RCS file: sys/sys/syscallsubr.h diff -N sys/sys/syscallsubr.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sys/syscallsubr.h 1 Sep 2002 16:44:22 -0000 @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2002 Ian Dowse. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SYS_SYSCALLSUBR_H_ +#define _SYS_SYSCALLSUBR_H_ + +#include +#include + +int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, + u_int buflen); +int kern_access(struct thread *td, char *path, enum uio_seg pathseg, + int flags); +int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg); +int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, + int mode); +int kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, + int gid); +int kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg); +int kern_futimes(struct thread *td, int fd, struct timeval *tptr, + enum uio_seg tptrseg); +int kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, + int uid, int gid); +int kern_link(struct thread *td, char *path, char *link, + enum uio_seg segflg); +int kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, + struct timeval *tptr, enum uio_seg tptrseg); +int kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, + int mode); +int kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, + int mode); +int kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, + int mode, int dev); +int kern_open(struct thread *td, char *path, enum uio_seg pathseg, + int flags, int mode); +int kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, + int data); +int kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, + char *buf, enum uio_seg bufseg, int count); +int kern_rename(struct thread *td, char *from, char *to, + enum uio_seg pathseg); +int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg); +int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, + fd_set *fd_ex, struct timeval *tvp); +int kern_sigaction(struct thread *td, int sig, struct sigaction *act, + struct sigaction *oact, int old); +int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss); +int kern_sigsuspend(struct thread *td, sigset_t mask); +int kern_symlink(struct thread *td, char *path, char *link, + enum uio_seg segflg); +int kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, + off_t length); +int kern_unlink(struct thread *td, char *path, enum uio_seg pathseg); +int kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, + struct timeval *tptr, enum uio_seg tptrseg); + +#endif /* !_SYS_SYSCALLSUBR_H_ */ +/* + * Copyright (c) 2002 Ian Dowse. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SYS_SYSCALLSUBR_H_ +#define _SYS_SYSCALLSUBR_H_ + +#include + +int sys_access(struct thread *td, char *path, enum uio_seg pathseg, + int flags); +int sys_chdir(struct thread *td, char *path, enum uio_seg pathseg); +int sys_chmod(struct thread *td, char *path, enum uio_seg pathseg, + int mode); +int sys_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, + int gid); +int sys_fcntl(struct thread *td, int fd, int cmd, intptr_t arg); +int sys_futimes(struct thread *td, int fd, struct timeval *tptr, + enum uio_seg tptrseg); +int sys_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, + int gid); +int sys_link(struct thread *td, char *path, char *link, + enum uio_seg segflg); +int sys_lutimes(struct thread *td, char *path, enum uio_seg pathseg, + struct timeval *tptr, enum uio_seg tptrseg); +int sys_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode); +int sys_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, + int mode); +int sys_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode, + int dev); +int sys_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, + int mode); +int sys_ptrace(struct thread *td, int req, pid_t pid, void *addr, + int data); +int sys_readlink(struct thread *td, char *path, enum uio_seg pathseg, + char *buf, enum uio_seg bufseg, int count); +int sys_rename(struct thread *td, char *from, char *to, + enum uio_seg pathseg); +int sys_rmdir(struct thread *td, char *path, enum uio_seg pathseg); +int sys_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, + fd_set *fd_ex, struct timeval *tvp); +int sys_sigaction(struct thread *td, int sig, struct sigaction *act, + struct sigaction *oact, int old); +int sys_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss); +int sys_sigsuspend(struct thread *td, sigset_t mask); +int sys_symlink(struct thread *td, char *path, char *link, + enum uio_seg segflg); +int sys_truncate(struct thread *td, char *path, enum uio_seg pathseg, + off_t length); +int sys_unlink(struct thread *td, char *path, enum uio_seg pathseg); +int sys_utimes(struct thread *td, char *path, enum uio_seg pathseg, + struct timeval *tptr, enum uio_seg tptrseg); + +#endif /* !_SYS_SYSCALLSUBR_H_ */ Index: sys/sys/vnode.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/sys/vnode.h,v retrieving revision 1.205 diff -u -r1.205 vnode.h --- sys/sys/vnode.h 21 Aug 2002 06:19:28 -0000 1.205 +++ sys/sys/vnode.h 1 Sep 2002 16:44:23 -0000 @@ -734,7 +734,6 @@ const char *filename, int line); #define vn_lock(vp,flags,p) debug_vn_lock(vp,flags,p,__FILE__,__LINE__) #endif -int vn_mkdir(char *path, int mode, enum uio_seg segflg, struct thread *td); int vn_open(struct nameidata *ndp, int *flagp, int cmode); int vn_open_cred(struct nameidata *ndp, int *flagp, int cmode, struct ucred *cred);