diff options
author | Rodney W. Grimes <rgrimes@FreeBSD.org> | 1994-05-25 09:21:21 +0000 |
---|---|---|
committer | Rodney W. Grimes <rgrimes@FreeBSD.org> | 1994-05-25 09:21:21 +0000 |
commit | 26f9a76710a312a951848542b9ca1f44100450e2 (patch) | |
tree | 9179427ac860211c445df663fd2b86267366bfba /sys/kern | |
parent | dbda0ec78e324aced444959e2c98b89b79f22812 (diff) | |
download | src-26f9a76710a312a951848542b9ca1f44100450e2.tar.gz src-26f9a76710a312a951848542b9ca1f44100450e2.zip |
The big 4.4BSD Lite to FreeBSD 2.0.0 (Development) patch.
Reviewed by: Rodney W. Grimes
Submitted by: John Dyson and David Greenman
Notes
Notes:
svn path=/head/; revision=1549
Diffstat (limited to 'sys/kern')
60 files changed, 2899 insertions, 700 deletions
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c index 5d69e097007f..4be4e5041f4a 100644 --- a/sys/kern/imgact_aout.c +++ b/sys/kern/imgact_aout.c @@ -31,15 +31,15 @@ * $Id: imgact_aout.c,v 1.3 1993/12/30 01:39:29 davidg Exp $ */ -#include "param.h" -#include "systm.h" -#include "resourcevar.h" -#include "exec.h" -#include "mman.h" -#include "imgact.h" -#include "kernel.h" +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/resourcevar.h> +#include <sys/exec.h> +#include <sys/mman.h> +#include <sys/imgact.h> +#include <sys/kernel.h> -#include "vm/vm.h" +#include <vm/vm.h> int exec_aout_imgact(iparams) @@ -135,8 +135,8 @@ exec_aout_imgact(iparams) a_out->a_text, /* size */ VM_PROT_READ | VM_PROT_EXECUTE, /* protection */ VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_WRITE, /* max protection */ - MAP_FILE | MAP_PRIVATE | MAP_FIXED, /* flags */ - iparams->vnodep, /* vnode */ + MAP_PRIVATE | MAP_FIXED, /* flags */ + (caddr_t)iparams->vnodep, /* vnode */ file_offset); /* offset */ if (error) return (error); @@ -151,7 +151,8 @@ exec_aout_imgact(iparams) &vmaddr, a_out->a_data, VM_PROT_READ | VM_PROT_WRITE | (a_out->a_text ? 0 : VM_PROT_EXECUTE), - VM_PROT_ALL, MAP_FILE | MAP_PRIVATE | MAP_FIXED, iparams->vnodep, + VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED, + (caddr_t) iparams->vnodep, file_offset + a_out->a_text); if (error) return (error); diff --git a/sys/kern/imgact_shell.c b/sys/kern/imgact_shell.c index 42b329759b54..e4f4d953c651 100644 --- a/sys/kern/imgact_shell.c +++ b/sys/kern/imgact_shell.c @@ -34,6 +34,7 @@ #include "param.h" #include "systm.h" #include "resourcevar.h" +#include <sys/exec.h> #include "imgact.h" #include "kernel.h" #include "machine/endian.h" diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index c6497153a695..f1fcc44c4b96 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -81,7 +81,7 @@ struct filedesc0 filedesc0; struct plimit limit0; struct vmspace vmspace0; struct proc *curproc = &proc0; -struct proc *initproc, *pageproc; +struct proc *initproc, *pageproc, *pagescanproc, *updateproc; int cmask = CMASK; extern struct user *proc0paddr; @@ -93,12 +93,26 @@ struct timeval runtime; static void start_init __P((struct proc *p, void *framep)); +#if __GNUC__ >= 2 +void __main() {} +#endif + +/* + * This table is filled in by the linker with functions that need to be + * called to initialize various pseudo-devices and whatnot. + */ +typedef void (*pseudo_func_t)(void); +extern const struct linker_set pseudo_set; +static const pseudo_func_t *pseudos = + (const pseudo_func_t *)&pseudo_set.ls_items[0]; + /* * System startup; initialize the world, create process 0, mount root * filesystem, and fork to create init and pagedaemon. Most of the * hard work is done in the lower-level initialization routines including * startup(), which does memory initialization and autoconfiguration. */ +void main(framep) void *framep; { @@ -178,7 +192,7 @@ main(framep) p->p_vmspace = &vmspace0; vmspace0.vm_refcnt = 1; pmap_pinit(&vmspace0.vm_pmap); - vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS), + vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS), trunc_page(VM_MAX_ADDRESS), TRUE); vmspace0.vm_map.pmap = &vmspace0.vm_pmap; p->p_addr = proc0paddr; /* XXX */ @@ -214,14 +228,12 @@ main(framep) /* Initialize clists. */ clist_init(); -#ifdef SYSVSHM - /* Initialize System V style shared memory. */ - shminit(); -#endif - - /* Attach pseudo-devices. */ - for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++) - (*pdev->pdev_attach)(pdev->pdev_count); + /* + * Attach pseudo-devices. + */ + while(*pseudos) { + (**pseudos++)(); + } /* * Initialize protocols. Block reception of incoming packets @@ -287,6 +299,37 @@ main(framep) vm_pageout(); /* NOTREACHED */ } +#if 1 + /* + * Start page scanner daemon (process 3). + */ + if (fork(p, (void *) NULL, rval)) + panic("failed fork page scanner daemon"); + if (rval[1]) { + p = curproc; + pagescanproc = p; + p->p_flag |= P_INMEM | P_SYSTEM; + bcopy("pagescan", p->p_comm, sizeof("pagescan")); + vm_pagescan(); + /*NOTREACHED*/ + } +#endif + + /* + * Start update daemon (process 4). + */ +#ifndef LAPTOP + if (fork(p, (void *) NULL, rval)) + panic("failed fork update daemon"); + if (rval[1]) { + p = curproc; + updateproc = p; + p->p_flag |= P_INMEM | P_SYSTEM; + bcopy("update", p->p_comm, sizeof("update")); + vfs_update(); + /*NOTREACHED*/ + } +#endif /* The scheduler is an infinite loop. */ scheduler(); @@ -331,10 +374,11 @@ start_init(p, framep) /* * Need just enough stack to hold the faked-up "execve()" arguments. */ - addr = trunc_page(VM_MAX_ADDRESS - PAGE_SIZE); + addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE); if (vm_allocate(&p->p_vmspace->vm_map, &addr, PAGE_SIZE, FALSE) != 0) panic("init: couldn't allocate argument space"); p->p_vmspace->vm_maxsaddr = (caddr_t)addr; + p->p_vmspace->vm_ssize = 1; for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) { /* @@ -377,8 +421,8 @@ start_init(p, framep) * Point at the arguments. */ args.fname = arg0; - args.argp = uap; - args.envp = NULL; + args.argv = uap; + args.envv = NULL; /* * Now try to exec the program. If can't for any reason diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 4b25c0695cfe..80cab9051dbe 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -138,6 +138,10 @@ int fstatfs(); int getfh(); #else #endif +int getdomainname(); +int setdomainname(); +int uname(); +int sysarch(); #ifdef SYSVSHM int shmsys(); #else @@ -308,7 +312,7 @@ struct sysent sysent[] = { { 0, nosys }, /* 68 = obsolete vwrite */ { 1, sbrk }, /* 69 = sbrk */ { 1, sstk }, /* 70 = sstk */ - { compat(7,mmap) }, /* 71 = old mmap */ + { compat(6,mmap) }, /* 71 = old mmap */ { 1, ovadvise }, /* 72 = vadvise */ { 2, munmap }, /* 73 = munmap */ { 3, mprotect }, /* 74 = mprotect */ @@ -415,10 +419,10 @@ struct sysent sysent[] = { #else { 0, nosys }, /* 161 = nosys */ #endif - { 0, nosys }, /* 162 = nosys */ - { 0, nosys }, /* 163 = nosys */ - { 0, nosys }, /* 164 = nosys */ - { 0, nosys }, /* 165 = nosys */ + { 2, getdomainname }, /* 162 = getdomainname */ + { 2, setdomainname }, /* 163 = setdomainname */ + { 1, uname }, /* 164 = uname */ + { 2, sysarch }, /* 165 = sysarch */ { 0, nosys }, /* 166 = nosys */ { 0, nosys }, /* 167 = nosys */ { 0, nosys }, /* 168 = nosys */ diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c index b752279d120a..3cbde510f84b 100644 --- a/sys/kern/kern_acct.c +++ b/sys/kern/kern_acct.c @@ -49,6 +49,7 @@ struct acct_args { char *fname; }; +int acct(a1, a2, a3) struct proc *a1; struct acct_args *a2; @@ -60,6 +61,7 @@ acct(a1, a2, a3) return (ENOSYS); } +void acct_process(a1) struct proc *a1; { diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index f42900cb75d2..4017e966ee69 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -511,6 +511,7 @@ statclock(frame) /* * Return information about system clocks. */ +int sysctl_clockrate(where, sizep) register char *where; size_t *sizep; diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 543946d3f8fd..9258e811f1be 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -68,6 +68,7 @@ struct getdtablesize_args { int dummy; }; /* ARGSUSED */ +int getdtablesize(p, uap, retval) struct proc *p; struct getdtablesize_args *uap; @@ -85,6 +86,7 @@ struct dup_args { u_int fd; }; /* ARGSUSED */ +int dup(p, uap, retval) struct proc *p; struct dup_args *uap; @@ -116,6 +118,7 @@ struct dup2_args { u_int to; }; /* ARGSUSED */ +int dup2(p, uap, retval) struct proc *p; struct dup2_args *uap; @@ -159,6 +162,7 @@ struct fcntl_args { int arg; }; /* ARGSUSED */ +int fcntl(p, uap, retval) struct proc *p; register struct fcntl_args *uap; @@ -324,6 +328,7 @@ struct close_args { int fd; }; /* ARGSUSED */ +int close(p, uap, retval) struct proc *p; struct close_args *uap; @@ -358,6 +363,7 @@ struct ofstat_args { struct ostat *sb; }; /* ARGSUSED */ +int ofstat(p, uap, retval) struct proc *p; register struct ofstat_args *uap; @@ -401,6 +407,7 @@ struct fstat_args { struct stat *sb; }; /* ARGSUSED */ +int fstat(p, uap, retval) struct proc *p; register struct fstat_args *uap; @@ -441,6 +448,7 @@ struct fpathconf_args { int name; }; /* ARGSUSED */ +int fpathconf(p, uap, retval) struct proc *p; register struct fpathconf_args *uap; @@ -476,6 +484,7 @@ fpathconf(p, uap, retval) */ int fdexpand; +int fdalloc(p, want, result) struct proc *p; int want; @@ -538,12 +547,14 @@ fdalloc(p, want, result) fdp->fd_nfiles = nfiles; fdexpand++; } + return (0); } /* * Check to see whether n user file descriptors * are available to the process p. */ +int fdavail(p, n) struct proc *p; register int n; @@ -566,6 +577,7 @@ fdavail(p, n) * Create a new open file structure and allocate * a file decriptor for the process that refers to it. */ +int falloc(p, resultfp, resultfd) register struct proc *p; struct file **resultfp; @@ -612,6 +624,7 @@ falloc(p, resultfp, resultfd) /* * Free a file descriptor. */ +void ffree(fp) register struct file *fp; { @@ -709,11 +722,40 @@ fdfree(p) } /* + * Close any files on exec? + */ +void +fdcloseexec(p) + struct proc *p; +{ + struct filedesc *fdp = p->p_fd; + struct file **fpp; + char *fdfp; + register int i; + + fpp = fdp->fd_ofiles; + fdfp = fdp->fd_ofileflags; + for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) + if (*fpp != NULL && (*fdfp & UF_EXCLOSE)) { + if (*fdfp & UF_MAPPED) + (void) munmapfd(i); + (void) closef(*fpp, p); + *fpp = NULL; + *fdfp = 0; + if (i < fdp->fd_freefile) + fdp->fd_freefile = i; + } + while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) + fdp->fd_lastfile--; +} + +/* * Internal form of close. * Decrement reference count on file structure. * Note: p may be NULL when closing a file * that was being passed in a message. */ +int closef(fp, p) register struct file *fp; register struct proc *p; @@ -771,6 +813,7 @@ struct flock_args { int how; }; /* ARGSUSED */ +int flock(p, uap, retval) struct proc *p; register struct flock_args *uap; @@ -816,6 +859,7 @@ flock(p, uap, retval) * references to this file will be direct to the other driver. */ /* ARGSUSED */ +int fdopen(dev, mode, type, p) dev_t dev; int mode, type; @@ -837,6 +881,7 @@ fdopen(dev, mode, type, p) /* * Duplicate the specified descriptor to a free descriptor. */ +int dupfdopen(fdp, indx, dfd, mode, error) register struct filedesc *fdp; register int indx, dfd; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index fbb4444d52bd..6717e4e53b6b 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,11 +1,6 @@ -/*- - * Copyright (c) 1982, 1986, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. +/* + * Copyright (c) 1993, David Greenman + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -17,16 +12,14 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * This product includes software developed by David Greenman + * 4. The name of the developer may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * 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 REGENTS OR CONTRIBUTORS BE LIABLE + * 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) @@ -35,30 +28,502 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: @(#)kern_exec.c 8.1 (Berkeley) 6/10/93 + * $Id: kern_execve.c,v 1.20 1994/03/26 12:24:27 davidg Exp $ */ #include <sys/param.h> -#include <sys/errno.h> -#include <sys/proc.h> +#include <sys/systm.h> +#include <sys/signalvar.h> +#include <sys/resourcevar.h> +#include <sys/kernel.h> +#include <sys/mount.h> +#include <sys/file.h> +#include <sys/acct.h> +#include <sys/exec.h> +#include <sys/imgact.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <sys/mman.h> +#include <sys/malloc.h> +#include <sys/syslog.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> + +#include <machine/reg.h> + +int exec_extract_strings __P((struct image_params *)); +int *exec_copyout_strings __P((struct image_params *)); + +/* + * execsw_set is constructed for us by the linker. Each of the items + * is a pointer to a `const struct execsw', hence the double pointer here. + */ +extern const struct linker_set execsw_set; +const struct execsw **execsw = (const struct execsw **)&execsw_set.ls_items[0]; + +/* + * execve() system call. + */ +int +execve(p, uap, retval) + struct proc *p; + register struct execve_args *uap; + int *retval; +{ + struct nameidata nd, *ndp; + char *stringbase, *stringp; + int *stack_base; + int error, resid, len, i; + struct image_params image_params, *iparams; + struct vnode *vnodep; + struct vattr attr; + char *image_header; + + iparams = &image_params; + bzero((caddr_t)iparams, sizeof(struct image_params)); + image_header = (char *)0; + + /* + * Initialize a few constants in the common area + */ + iparams->proc = p; + iparams->uap = uap; + iparams->attr = &attr; + + /* + * Allocate temporary demand zeroed space for argument and + * environment strings + */ + error = vm_allocate(kernel_map, (vm_offset_t *)&iparams->stringbase, + ARG_MAX, TRUE); + if (error) { + log(LOG_WARNING, "execve: failed to allocate string space\n"); + return (error); + } + + if (!iparams->stringbase) { + error = ENOMEM; + goto exec_fail; + } + iparams->stringp = iparams->stringbase; + iparams->stringspace = ARG_MAX; + + /* + * Translate the file name. namei() returns a vnode pointer + * in ni_vp amoung other things. + */ + ndp = &nd; + ndp->ni_cnd.cn_nameiop = LOOKUP; + ndp->ni_cnd.cn_flags = LOCKLEAF | FOLLOW | SAVENAME; + ndp->ni_cnd.cn_proc = curproc; + ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred; + ndp->ni_segflg = UIO_USERSPACE; + ndp->ni_dirp = uap->fname; + +interpret: + + error = namei(ndp); + if (error) { + vm_deallocate(kernel_map, (vm_offset_t)iparams->stringbase, + ARG_MAX); + goto exec_fail; + } + + iparams->vnodep = vnodep = ndp->ni_vp; + + if (vnodep == NULL) { + error = ENOEXEC; + goto exec_fail_dealloc; + } + + /* + * Check file permissions (also 'opens' file) + */ + error = exec_check_permissions(iparams); + if (error) + goto exec_fail_dealloc; + + /* + * Map the image header (first page) of the file into + * kernel address space + */ + error = vm_mmap(kernel_map, /* map */ + (vm_offset_t *)&image_header, /* address */ + PAGE_SIZE, /* size */ + VM_PROT_READ, /* protection */ + VM_PROT_READ, /* max protection */ + 0, /* flags */ + (caddr_t)vnodep, /* vnode */ + 0); /* offset */ + if (error) { + uprintf("mmap failed: %d\n",error); + goto exec_fail_dealloc; + } + iparams->image_header = image_header; + + /* + * Loop through list of image activators, calling each one. + * If there is no match, the activator returns -1. If there + * is a match, but there was an error during the activation, + * the error is returned. Otherwise 0 means success. If the + * image is interpreted, loop back up and try activating + * the interpreter. + */ + for (i = 0; execsw[i]; ++i) { + if (execsw[i]->ex_imgact) + error = (*execsw[i]->ex_imgact)(iparams); + else + continue; + + if (error == -1) + continue; + if (error) + goto exec_fail_dealloc; + if (iparams->interpreted) { + /* free old vnode and name buffer */ + vput(ndp->ni_vp); + FREE(ndp->ni_cnd.cn_pnbuf, M_NAMEI); + if (vm_deallocate(kernel_map, + (vm_offset_t)image_header, PAGE_SIZE)) + panic("execve: header dealloc failed (1)"); + + /* set new name to that of the interpreter */ + ndp->ni_segflg = UIO_SYSSPACE; + ndp->ni_dirp = iparams->interpreter_name; + ndp->ni_cnd.cn_nameiop = LOOKUP; + ndp->ni_cnd.cn_flags = LOCKLEAF | FOLLOW | SAVENAME; + ndp->ni_cnd.cn_proc = curproc; + ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred; + goto interpret; + } + break; + } + /* If we made it through all the activators and none matched, exit. */ + if (error == -1) { + error = ENOEXEC; + goto exec_fail_dealloc; + } + + /* + * Copy out strings (args and env) and initialize stack base + */ + stack_base = exec_copyout_strings(iparams); + p->p_vmspace->vm_minsaddr = (char *)stack_base; + + /* + * Stuff argument count as first item on stack + */ + *(--stack_base) = iparams->argc; + + /* close files on exec */ + fdcloseexec(p); + + /* reset caught signals */ + execsigs(p); + + /* name this process - nameiexec(p, ndp) */ + len = min(ndp->ni_cnd.cn_namelen,MAXCOMLEN); + bcopy(ndp->ni_cnd.cn_nameptr, p->p_comm, len); + p->p_comm[len] = 0; + + /* + * mark as executable, wakeup any process that was vforked and tell + * it that it now has it's own resources back + */ + p->p_flag |= P_EXEC; + if (p->p_pptr && (p->p_flag & P_PPWAIT)) { + p->p_flag &= ~P_PPWAIT; + wakeup((caddr_t)p->p_pptr); + } + + /* implement set userid/groupid */ + p->p_flag &= ~P_SUGID; + + /* + * Turn off kernel tracing for set-id programs, except for + * root. + */ + if (p->p_tracep && (attr.va_mode & (VSUID | VSGID)) && + suser(p->p_ucred, &p->p_acflag)) { + p->p_traceflag = 0; + vrele(p->p_tracep); + p->p_tracep = 0; + } + if ((attr.va_mode & VSUID) && (p->p_flag & P_TRACED) == 0) { + p->p_ucred = crcopy(p->p_ucred); + p->p_ucred->cr_uid = attr.va_uid; + p->p_flag |= P_SUGID; + } + if ((attr.va_mode & VSGID) && (p->p_flag & P_TRACED) == 0) { + p->p_ucred = crcopy(p->p_ucred); + p->p_ucred->cr_groups[0] = attr.va_gid; + p->p_flag |= P_SUGID; + } + + /* + * Implement correct POSIX saved uid behavior. + */ + p->p_cred->p_svuid = p->p_ucred->cr_uid; + p->p_cred->p_svgid = p->p_ucred->cr_gid; + + /* mark vnode pure text */ + ndp->ni_vp->v_flag |= VTEXT; + + /* + * If tracing the process, trap to debugger so breakpoints + * can be set before the program executes. + */ + if (p->p_flag & P_TRACED) + psignal(p, SIGTRAP); + + /* clear "fork but no exec" flag, as we _are_ execing */ + p->p_acflag &= ~AFORK; + + /* Set entry address */ + setregs(p, iparams->entry_addr, stack_base); + + /* + * free various allocated resources + */ + if (vm_deallocate(kernel_map, (vm_offset_t)iparams->stringbase, ARG_MAX)) + panic("execve: string buffer dealloc failed (1)"); + if (vm_deallocate(kernel_map, (vm_offset_t)image_header, PAGE_SIZE)) + panic("execve: header dealloc failed (2)"); + vput(ndp->ni_vp); + FREE(ndp->ni_cnd.cn_pnbuf, M_NAMEI); + + return (0); + +exec_fail_dealloc: + if (iparams->stringbase && iparams->stringbase != (char *)-1) + if (vm_deallocate(kernel_map, (vm_offset_t)iparams->stringbase, + ARG_MAX)) + panic("execve: string buffer dealloc failed (2)"); + if (iparams->image_header && iparams->image_header != (char *)-1) + if (vm_deallocate(kernel_map, + (vm_offset_t)iparams->image_header, PAGE_SIZE)) + panic("execve: header dealloc failed (3)"); + vput(ndp->ni_vp); + FREE(ndp->ni_cnd.cn_pnbuf, M_NAMEI); + +exec_fail: + if (iparams->vmspace_destroyed) { + /* sorry, no more process anymore. exit gracefully */ +#if 0 /* XXX */ + vm_deallocate(&vs->vm_map, USRSTACK - MAXSSIZ, MAXSSIZ); +#endif + exit1(p, W_EXITCODE(0, SIGABRT)); + /* NOT REACHED */ + return(0); + } else { + return(error); + } +} + +/* + * Destroy old address space, and allocate a new stack + * The new stack is only SGROWSIZ large because it is grown + * automatically in trap.c. + */ +int +exec_new_vmspace(iparams) + struct image_params *iparams; +{ + int error; + struct vmspace *vmspace = iparams->proc->p_vmspace; + caddr_t stack_addr = (caddr_t) (USRSTACK - SGROWSIZ); + + iparams->vmspace_destroyed = 1; + + /* Blow away entire process VM */ + vm_deallocate(&vmspace->vm_map, 0, USRSTACK); + + /* Allocate a new stack */ + error = vm_allocate(&vmspace->vm_map, (vm_offset_t *)&stack_addr, + SGROWSIZ, FALSE); + if (error) + return(error); + + vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT; + + /* Initialize maximum stack address */ + vmspace->vm_maxsaddr = (char *)USRSTACK - MAXSSIZ; + + return(0); +} + +/* + * Copy out argument and environment strings from the old process + * address space into the temporary string buffer. + */ +int +exec_extract_strings(iparams) + struct image_params *iparams; +{ + char **argv, **envv; + char *argp, *envp; + int length; + + /* + * extract arguments first + */ + + argv = iparams->uap->argv; + + if (argv) + while (argp = (caddr_t) fuword(argv++)) { + if (argp == (caddr_t) -1) + return (EFAULT); + if (copyinstr(argp, iparams->stringp, iparams->stringspace, + &length) == ENAMETOOLONG) + return(E2BIG); + iparams->stringspace -= length; + iparams->stringp += length; + iparams->argc++; + } + + /* + * extract environment strings + */ + + envv = iparams->uap->envv; + + if (envv) + while (envp = (caddr_t) fuword(envv++)) { + if (envp == (caddr_t) -1) + return (EFAULT); + if (copyinstr(envp, iparams->stringp, iparams->stringspace, + &length) == ENAMETOOLONG) + return(E2BIG); + iparams->stringspace -= length; + iparams->stringp += length; + iparams->envc++; + } + + return (0); +} + +/* + * Copy strings out to the new process address space, constructing + * new arg and env vector tables. Return a pointer to the base + * so that it can be used as the initial stack pointer. + */ +int * +exec_copyout_strings(iparams) + struct image_params *iparams; +{ + int argc, envc; + char **vectp; + char *stringp, *destp; + int *stack_base; + int vect_table_size, string_table_size; + + /* + * Calculate string base and vector table pointers. + */ + destp = (caddr_t) ((caddr_t)USRSTACK - + roundup((ARG_MAX - iparams->stringspace), sizeof(char *))); + /* + * The '+ 2' is for the null pointers at the end of each of the + * arg and env vector sets + */ + vectp = (char **) (destp - + (iparams->argc + iparams->envc + 2) * sizeof(char *)); + + /* + * vectp also becomes our initial stack base + */ + stack_base = (int *)vectp; + + stringp = iparams->stringbase; + argc = iparams->argc; + envc = iparams->envc; + + for (; argc > 0; --argc) { + *(vectp++) = destp; + while (*destp++ = *stringp++); + } + + /* a null vector table pointer seperates the argp's from the envp's */ + *(vectp++) = NULL; + + for (; envc > 0; --envc) { + *(vectp++) = destp; + while (*destp++ = *stringp++); + } + + /* end of vector table is a null pointer */ + *vectp = NULL; + + return (stack_base); +} /* - * exec system call + * Check permissions of file to execute. + * Return 0 for success or error code on failure. */ -struct execve_args { - char *fname; - char **argp; - char **envp; -}; -/* ARGSUSED */ -execve(a1, a2, a3) - struct proc *a1; - struct execve_args *a2; - int *a3; +int +exec_check_permissions(iparams) + struct image_params *iparams; { + struct proc *p = iparams->proc; + struct vnode *vnodep = iparams->vnodep; + struct vattr *attr = iparams->attr; + int error; + + /* + * Check number of open-for-writes on the file and deny execution + * if there are any. + */ + if (vnodep->v_writecount) { + return (ETXTBSY); + } + + /* Get file attributes */ + error = VOP_GETATTR(vnodep, attr, p->p_ucred, p); + if (error) + return (error); + + /* + * 1) Check if file execution is disabled for the filesystem that this + * file resides on. + * 2) Insure that at least one execute bit is on - otherwise root + * will always succeed, and we don't want to happen unless the + * file really is executable. + * 3) Insure that the file is a regular file. + */ + if ((vnodep->v_mount->mnt_flag & MNT_NOEXEC) || + ((attr->va_mode & 0111) == 0) || + (attr->va_type != VREG)) { + return (EACCES); + } /* - * Body deleted. + * Zero length files can't be exec'd */ - return (ENOSYS); + if (attr->va_size == 0) + return (ENOEXEC); + + /* + * Disable setuid/setgid if the filesystem prohibits it or if + * the process is being traced. + */ + if ((vnodep->v_mount->mnt_flag & MNT_NOSUID) || (p->p_flag & P_TRACED)) + attr->va_mode &= ~(VSUID | VSGID); + + /* + * Check for execute permission to file based on current credentials. + * Then call filesystem specific open routine (which does nothing + * in the general case). + */ + error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p); + if (error) + return (error); + + error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p); + if (error) + return (error); + + return (0); } diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 03353c72d1d1..7db9830abb67 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -84,6 +84,7 @@ exit(p, uap, retval) exit1(p, W_EXITCODE(uap->rval, 0)); /* NOTREACHED */ + while (1); } /* @@ -293,6 +294,7 @@ struct wait_args { #define GETPS(rp) (rp)[PS] #endif +int owait(p, uap, retval) struct proc *p; register struct wait_args *uap; @@ -317,6 +319,7 @@ owait(p, uap, retval) return (wait1(p, uap, retval)); } +int wait4(p, uap, retval) struct proc *p; struct wait_args *uap; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 8bec2fa5d5fe..c285017013f4 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -55,6 +55,7 @@ struct fork_args { int dummy; }; /* ARGSUSED */ +int fork(p, uap, retval) struct proc *p; struct fork_args *uap; @@ -65,6 +66,7 @@ fork(p, uap, retval) } /* ARGSUSED */ +int vfork(p, uap, retval) struct proc *p; struct fork_args *uap; @@ -76,6 +78,7 @@ vfork(p, uap, retval) int nprocs = 1; /* process 0 */ +int fork1(p1, isvfork, retval) register struct proc *p1; int isvfork, retval[]; diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 763cfb257ffb..4b6f721c3a26 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -44,6 +44,8 @@ #include <sys/malloc.h> #include <sys/syslog.h> +void ktrwrite __P((struct vnode *, struct ktr_header *)); + struct ktr_header * ktrgetheader(type) int type; @@ -60,6 +62,7 @@ ktrgetheader(type) return (kth); } +void ktrsyscall(vp, code, narg, args) struct vnode *vp; int code, narg, args[]; @@ -86,6 +89,7 @@ ktrsyscall(vp, code, narg, args) p->p_traceflag &= ~KTRFAC_ACTIVE; } +void ktrsysret(vp, code, error, retval) struct vnode *vp; int code, error, retval; @@ -108,6 +112,7 @@ ktrsysret(vp, code, error, retval) p->p_traceflag &= ~KTRFAC_ACTIVE; } +void ktrnamei(vp, path) struct vnode *vp; char *path; @@ -125,6 +130,7 @@ ktrnamei(vp, path) p->p_traceflag &= ~KTRFAC_ACTIVE; } +void ktrgenio(vp, fd, rw, iov, len, error) struct vnode *vp; int fd; @@ -166,6 +172,7 @@ done: p->p_traceflag &= ~KTRFAC_ACTIVE; } +void ktrpsig(vp, sig, action, mask, code) struct vnode *vp; int sig; @@ -190,6 +197,7 @@ ktrpsig(vp, sig, action, mask, code) p->p_traceflag &= ~KTRFAC_ACTIVE; } +void ktrcsw(vp, out, user) struct vnode *vp; int out, user; @@ -222,6 +230,7 @@ struct ktrace_args { int pid; }; /* ARGSUSED */ +int ktrace(curp, uap, retval) struct proc *curp; register struct ktrace_args *uap; @@ -357,6 +366,7 @@ ktrops(curp, p, ops, facs, vp) return (1); } +int ktrsetchildren(curp, top, ops, facs, vp) struct proc *curp, *top; int ops, facs; @@ -392,6 +402,7 @@ ktrsetchildren(curp, top, ops, facs, vp) /*NOTREACHED*/ } +void ktrwrite(vp, kth) struct vnode *vp; register struct ktr_header *kth; @@ -446,6 +457,7 @@ ktrwrite(vp, kth) * * TODO: check groups. use caller effective gid. */ +int ktrcanset(callp, targetp) struct proc *callp, *targetp; { diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index c6276bc73cf4..3da06d9c04a8 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -34,6 +34,7 @@ */ #include <sys/param.h> +#include <sys/systm.h> #include <sys/proc.h> #include <sys/map.h> #include <sys/kernel.h> @@ -348,6 +349,7 @@ free(addr, type) /* * Initialize the kernel memory allocator */ +void kmeminit() { register long indx; diff --git a/sys/kern/kern_physio.c b/sys/kern/kern_physio.c index 1eaae3599dee..9e0405fc6abb 100644 --- a/sys/kern/kern_physio.c +++ b/sys/kern/kern_physio.c @@ -1,41 +1,20 @@ -/*- - * Copyright (c) 1982, 1986, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. +/* + * Copyright (c) 1994 John S. Dyson + * 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. + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)kern_physio.c 8.1 (Berkeley) 6/10/93 + * 3. Absolutely no warranty of function or purpose is made by the author + * John S. Dyson. + * 4. Modifications may be freely made to this file if the above conditions + * are met. */ #include <sys/param.h> @@ -43,51 +22,150 @@ #include <sys/buf.h> #include <sys/conf.h> #include <sys/proc.h> +#include <vm/vm.h> -physio(a1, a2, a3, a4, a5, a6) - int (*a1)(); - struct buf *a2; - dev_t a3; - int a4; - u_int (*a5)(); - struct uio *a6; +static void physwakeup(); + +int +physio(strategy, bp, dev, rw, minp, uio) + int (*strategy)(); + struct buf *bp; + dev_t dev; + int rw; + u_int (*minp)(); + struct uio *uio; { + int i; + int bp_alloc = (bp == 0); + int bufflags = rw?B_READ:0; + int error; + int spl; + +/* + * keep the process from being swapped + */ + curproc->p_flag |= P_PHYSIO; + + /* create and build a buffer header for a transfer */ + + if (bp_alloc) { + bp = (struct buf *)getpbuf(); + } else { + spl = splbio(); + while (bp->b_flags & B_BUSY) { + bp->b_flags |= B_WANTED; + tsleep((caddr_t)bp, PRIBIO, "physbw", 0); + } + bp->b_flags |= B_BUSY; + splx(spl); + } + + bp->b_proc = curproc; + bp->b_dev = dev; + error = bp->b_error = 0; + + for(i=0;i<uio->uio_iovcnt;i++) { + while( uio->uio_iov[i].iov_len) { + vm_offset_t v, lastv, pa; + caddr_t adr; + + bp->b_bcount = uio->uio_iov[i].iov_len; + bp->b_bufsize = bp->b_bcount; + bp->b_flags = B_BUSY | B_PHYS | B_CALL | bufflags; + bp->b_iodone = physwakeup; + bp->b_data = uio->uio_iov[i].iov_base; + bp->b_blkno = btodb(uio->uio_offset); + + + if (rw && !useracc(bp->b_data, bp->b_bufsize, B_WRITE)) { + error = EFAULT; + goto doerror; + } + if (!rw && !useracc(bp->b_data, bp->b_bufsize, B_READ)) { + error = EFAULT; + goto doerror; + } + + vmapbuf(bp); + + /* perform transfer */ + (*strategy)(bp); + + spl = splbio(); + while ((bp->b_flags & B_DONE) == 0) + tsleep((caddr_t)bp, PRIBIO, "physstr", 0); + splx(spl); - /* - * Body deleted. - */ - return (EIO); + vunmapbuf(bp); + + /* + * update the uio data + */ + { + int iolen = bp->b_bcount - bp->b_resid; + uio->uio_iov[i].iov_len -= iolen; + uio->uio_iov[i].iov_base += iolen; + uio->uio_resid -= iolen; + uio->uio_offset += iolen; + } + + /* + * check for an error + */ + if( bp->b_flags & B_ERROR) { + error = bp->b_error; + goto doerror; + } + } + } + + +doerror: + if (bp_alloc) { + relpbuf(bp); + } else { + bp->b_flags &= ~(B_BUSY|B_PHYS); + if( bp->b_flags & B_WANTED) { + bp->b_flags &= ~B_WANTED; + wakeup((caddr_t)bp); + } + } +/* + * allow the process to be swapped + */ + curproc->p_flag &= ~P_PHYSIO; + + return (error); } u_int -minphys(a1) - struct buf *a1; +minphys(struct buf *bp) { - /* - * Body deleted. - */ - return (0); + if( bp->b_bcount > MAXBSIZE) { + bp->b_bcount = MAXBSIZE; + } + return bp->b_bcount; } -/* - * Do a read on a device for a user process. - */ -rawread(dev, uio) - dev_t dev; - struct uio *uio; +int +rawread(dev_t dev, struct uio *uio) { return (physio(cdevsw[major(dev)].d_strategy, (struct buf *)NULL, - dev, B_READ, minphys, uio)); + dev, 1, minphys, uio)); } -/* - * Do a write on a device for a user process. - */ -rawwrite(dev, uio) - dev_t dev; - struct uio *uio; +int +rawwrite(dev_t dev, struct uio *uio) { return (physio(cdevsw[major(dev)].d_strategy, (struct buf *)NULL, - dev, B_WRITE, minphys, uio)); + dev, 0, minphys, uio)); +} + +static void +physwakeup(bp) + struct buf *bp; +{ + wakeup((caddr_t) bp); + bp->b_flags &= ~B_CALL; } diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 91d9e212d388..63a22c966c5a 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -49,6 +49,9 @@ #include <sys/ioctl.h> #include <sys/tty.h> +void pgdelete __P((struct pgrp *)); +void fixjobc __P((struct proc *, struct pgrp *, int)); + /* * Structure associated with user cacheing. */ @@ -64,6 +67,7 @@ u_long uihash; /* size of hash table - 1 */ /* * Allocate a hash table. */ +void usrinfoinit() { @@ -116,6 +120,7 @@ chgproccnt(uid, diff) /* * Is p an inferior of the current process? */ +int inferior(p) register struct proc *p; { @@ -160,6 +165,7 @@ pgfind(pgid) /* * Move p to a new or existing process group (and session) */ +int enterpgrp(p, pgid, mksess) register struct proc *p; pid_t pgid; @@ -259,6 +265,7 @@ enterpgrp(p, pgid, mksess) /* * remove process from process group */ +int leavepgrp(p) register struct proc *p; { @@ -283,6 +290,7 @@ leavepgrp(p) /* * delete a process group */ +void pgdelete(pgrp) register struct pgrp *pgrp; { @@ -318,6 +326,7 @@ static void orphanpg(); * entering == 0 => p is leaving specified group. * entering == 1 => p is entering specified group. */ +void fixjobc(p, pgrp, entering) register struct proc *p; register struct pgrp *pgrp; diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index ef400770e20a..1e205eecd5ae 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -56,6 +56,7 @@ struct args { }; /* ARGSUSED */ +int getpid(p, uap, retval) struct proc *p; struct args *uap; @@ -70,6 +71,7 @@ getpid(p, uap, retval) } /* ARGSUSED */ +int getppid(p, uap, retval) struct proc *p; struct args *uap; @@ -81,6 +83,7 @@ getppid(p, uap, retval) } /* Get process group ID; note that POSIX getpgrp takes no parameter */ +int getpgrp(p, uap, retval) struct proc *p; struct args *uap; @@ -92,6 +95,7 @@ getpgrp(p, uap, retval) } /* ARGSUSED */ +int getuid(p, uap, retval) struct proc *p; struct args *uap; @@ -106,6 +110,7 @@ getuid(p, uap, retval) } /* ARGSUSED */ +int geteuid(p, uap, retval) struct proc *p; struct args *uap; @@ -117,6 +122,7 @@ geteuid(p, uap, retval) } /* ARGSUSED */ +int getgid(p, uap, retval) struct proc *p; struct args *uap; @@ -136,6 +142,7 @@ getgid(p, uap, retval) * correctly in a library function. */ /* ARGSUSED */ +int getegid(p, uap, retval) struct proc *p; struct args *uap; @@ -150,6 +157,7 @@ struct getgroups_args { u_int gidsetsize; gid_t *gidset; }; +int getgroups(p, uap, retval) struct proc *p; register struct getgroups_args *uap; @@ -174,6 +182,7 @@ getgroups(p, uap, retval) } /* ARGSUSED */ +int setsid(p, uap, retval) register struct proc *p; struct args *uap; @@ -207,6 +216,7 @@ struct setpgid_args { int pgid; /* target pgrp id */ }; /* ARGSUSED */ +int setpgid(curp, uap, retval) struct proc *curp; register struct setpgid_args *uap; @@ -239,6 +249,7 @@ struct setuid_args { uid_t uid; }; /* ARGSUSED */ +int setuid(p, uap, retval) struct proc *p; struct setuid_args *uap; @@ -271,6 +282,7 @@ struct seteuid_args { uid_t euid; }; /* ARGSUSED */ +int seteuid(p, uap, retval) struct proc *p; struct seteuid_args *uap; @@ -298,6 +310,7 @@ struct setgid_args { gid_t gid; }; /* ARGSUSED */ +int setgid(p, uap, retval) struct proc *p; struct setgid_args *uap; @@ -322,6 +335,7 @@ struct setegid_args { gid_t egid; }; /* ARGSUSED */ +int setegid(p, uap, retval) struct proc *p; struct setegid_args *uap; @@ -346,6 +360,7 @@ struct setgroups_args { gid_t *gidset; }; /* ARGSUSED */ +int setgroups(p, uap, retval) struct proc *p; struct setgroups_args *uap; @@ -374,6 +389,7 @@ struct setreuid_args { int euid; }; /* ARGSUSED */ +int osetreuid(p, uap, retval) register struct proc *p; struct setreuid_args *uap; @@ -401,6 +417,7 @@ struct setregid_args { int egid; }; /* ARGSUSED */ +int osetregid(p, uap, retval) register struct proc *p; struct setregid_args *uap; @@ -427,6 +444,7 @@ osetregid(p, uap, retval) /* * Check if gid is a member of the group set. */ +int groupmember(gid, cred) gid_t gid; register struct ucred *cred; @@ -447,6 +465,7 @@ groupmember(gid, cred) * indicating use of super-powers. * Returns 0 or error. */ +int suser(cred, acflag) struct ucred *cred; short *acflag; @@ -477,6 +496,7 @@ crget() * Free a cred structure. * Throws away space when ref count gets to 0. */ +void crfree(cr) struct ucred *cr; { @@ -529,6 +549,7 @@ struct getlogin_args { u_int namelen; }; /* ARGSUSED */ +int getlogin(p, uap, retval) struct proc *p; struct getlogin_args *uap; @@ -548,6 +569,7 @@ struct setlogin_args { char *namebuf; }; /* ARGSUSED */ +int setlogin(p, uap, retval) struct proc *p; struct setlogin_args *uap; diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 68e9dfbc86de..e38471a41e5b 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -39,6 +39,7 @@ */ #include <sys/param.h> +#include <sys/systm.h> #include <sys/kernel.h> #include <sys/file.h> #include <sys/resourcevar.h> @@ -55,6 +56,7 @@ struct getpriority_args { int which; int who; }; +int getpriority(curp, uap, retval) struct proc *curp; register struct getpriority_args *uap; @@ -114,6 +116,7 @@ struct setpriority_args { int prio; }; /* ARGSUSED */ +int setpriority(curp, uap, retval) struct proc *curp; register struct setpriority_args *uap; @@ -167,6 +170,7 @@ setpriority(curp, uap, retval) return (error); } +int donice(curp, chgp, n) register struct proc *curp, *chgp; register int n; @@ -194,6 +198,7 @@ struct setrlimit_args { struct orlimit *lim; }; /* ARGSUSED */ +int osetrlimit(p, uap, retval) struct proc *p; register struct setrlimit_args *uap; @@ -216,6 +221,7 @@ struct getrlimit_args { struct orlimit *rlp; }; /* ARGSUSED */ +int ogetrlimit(p, uap, retval) struct proc *p; register struct getrlimit_args *uap; @@ -240,6 +246,7 @@ struct __setrlimit_args { struct rlimit *lim; }; /* ARGSUSED */ +int setrlimit(p, uap, retval) struct proc *p; register struct __setrlimit_args *uap; @@ -254,13 +261,13 @@ setrlimit(p, uap, retval) return (dosetrlimit(p, uap->which, &alim)); } +int dosetrlimit(p, which, limp) struct proc *p; u_int which; struct rlimit *limp; { register struct rlimit *alimp; - extern unsigned maxdmap; int error; if (which >= RLIM_NLIMITS) @@ -282,17 +289,17 @@ dosetrlimit(p, which, limp) switch (which) { case RLIMIT_DATA: - if (limp->rlim_cur > maxdmap) - limp->rlim_cur = maxdmap; - if (limp->rlim_max > maxdmap) - limp->rlim_max = maxdmap; + if (limp->rlim_cur > MAXDSIZ) + limp->rlim_cur = MAXDSIZ; + if (limp->rlim_max > MAXDSIZ) + limp->rlim_max = MAXDSIZ; break; case RLIMIT_STACK: - if (limp->rlim_cur > maxdmap) - limp->rlim_cur = maxdmap; - if (limp->rlim_max > maxdmap) - limp->rlim_max = maxdmap; + if (limp->rlim_cur > MAXSSIZ) + limp->rlim_cur = MAXSSIZ; + if (limp->rlim_max > MAXSSIZ) + limp->rlim_max = MAXSSIZ; /* * Stack is allocated to the max at exec time with only * "rlim_cur" bytes accessible. If stack limit is going @@ -342,6 +349,7 @@ struct __getrlimit_args { struct rlimit *rlp; }; /* ARGSUSED */ +int getrlimit(p, uap, retval) struct proc *p; register struct __getrlimit_args *uap; @@ -358,6 +366,7 @@ getrlimit(p, uap, retval) * Transform the running time and tick information in proc p into user, * system, and interrupt time usage. */ +void calcru(p, up, sp, ip) register struct proc *p; register struct timeval *up; @@ -415,6 +424,7 @@ struct getrusage_args { struct rusage *rusage; }; /* ARGSUSED */ +int getrusage(p, uap, retval) register struct proc *p; register struct getrusage_args *uap; @@ -440,6 +450,7 @@ getrusage(p, uap, retval) sizeof (struct rusage))); } +void ruadd(ru, ru2) register struct rusage *ru, *ru2; { diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 3dcff922c399..f778c364d670 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -62,6 +62,10 @@ #include <vm/vm.h> #include <sys/user.h> /* for coredump */ +void setsigvec __P((struct proc *, int, struct sigaction *)); +void stop __P((struct proc *)); +void sigexit __P((struct proc *, int)); + /* * Can process p, with pcred pc, send the signal signum to process q? */ @@ -79,6 +83,7 @@ struct sigaction_args { struct sigaction *osa; }; /* ARGSUSED */ +int sigaction(p, uap, retval) struct proc *p; register struct sigaction_args *uap; @@ -119,6 +124,7 @@ sigaction(p, uap, retval) return (0); } +void setsigvec(p, signum, sa) register struct proc *p; int signum; @@ -237,6 +243,7 @@ struct sigprocmask_args { int how; sigset_t mask; }; +int sigprocmask(p, uap, retval) register struct proc *p; struct sigprocmask_args *uap; @@ -272,6 +279,7 @@ struct sigpending_args { int dummy; }; /* ARGSUSED */ +int sigpending(p, uap, retval) struct proc *p; struct sigpending_args *uap; @@ -292,6 +300,7 @@ struct osigvec_args { struct sigvec *osv; }; /* ARGSUSED */ +int osigvec(p, uap, retval) struct proc *p; register struct osigvec_args *uap; @@ -348,6 +357,7 @@ osigvec(p, uap, retval) struct osigblock_args { int mask; }; +int osigblock(p, uap, retval) register struct proc *p; struct osigblock_args *uap; @@ -364,6 +374,7 @@ osigblock(p, uap, retval) struct osigsetmask_args { int mask; }; +int osigsetmask(p, uap, retval) struct proc *p; struct osigsetmask_args *uap; @@ -387,6 +398,7 @@ struct sigsuspend_args { sigset_t mask; }; /* ARGSUSED */ +int sigsuspend(p, uap, retval) register struct proc *p; struct sigsuspend_args *uap; @@ -416,6 +428,7 @@ struct osigstack_args { struct sigstack *oss; }; /* ARGSUSED */ +int osigstack(p, uap, retval) struct proc *p; register struct osigstack_args *uap; @@ -447,6 +460,7 @@ struct sigaltstack_args { struct sigaltstack *oss; }; /* ARGSUSED */ +int sigaltstack(p, uap, retval) struct proc *p; register struct sigaltstack_args *uap; @@ -485,6 +499,7 @@ struct kill_args { int signum; }; /* ARGSUSED */ +int kill(cp, uap, retval) register struct proc *cp; register struct kill_args *uap; @@ -522,6 +537,7 @@ struct okillpg_args { int signum; }; /* ARGSUSED */ +int okillpg(p, uap, retval) struct proc *p; register struct okillpg_args *uap; @@ -538,6 +554,7 @@ okillpg(p, uap, retval) * Common code for kill process group/broadcast kill. * cp is calling process. */ +int killpg1(cp, signum, pgid, all) register struct proc *cp; int signum, pgid, all; @@ -864,6 +881,7 @@ out: * while (signum = CURSIG(curproc)) * postsig(signum); */ +int issignal(p) register struct proc *p; { @@ -1004,6 +1022,7 @@ issignal(p) * via wakeup. Signals are handled elsewhere. The process must not be * on the run queue. */ +void stop(p) register struct proc *p; { @@ -1085,6 +1104,7 @@ postsig(signum) /* * Kill the current process for stated reason. */ +void killproc(p, why) struct proc *p; char *why; @@ -1103,6 +1123,7 @@ killproc(p, why) * If dumping core, save the signal number for the debugger. Calls exit and * does not return. */ +void sigexit(p, signum) register struct proc *p; int signum; @@ -1122,6 +1143,7 @@ sigexit(p, signum) * Dump core, into a file named "progname.core", unless the process was * setuid/setgid. */ +int coredump(p) register struct proc *p; { @@ -1186,6 +1208,7 @@ struct nosys_args { int dummy; }; /* ARGSUSED */ +int nosys(p, args, retval) struct proc *p; struct nosys_args *args; diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c index 5c12afcba33b..8eb4dee65a7c 100644 --- a/sys/kern/kern_subr.c +++ b/sys/kern/kern_subr.c @@ -44,6 +44,7 @@ #include <sys/malloc.h> #include <sys/queue.h> +int uiomove(cp, n, uio) register caddr_t cp; register int n; @@ -101,6 +102,7 @@ uiomove(cp, n, uio) /* * Give next character to user as result of read. */ +int ureadc(c, uio) register int c; register struct uio *uio; @@ -143,6 +145,7 @@ again: /* * Get next character written in by user from uio. */ +int uwritec(uio) struct uio *uio; { diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 1c2a578f3036..a299dbaf7aaa 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -600,6 +600,7 @@ mi_switch() * Initialize the (doubly-linked) run queues * to be empty. */ +void rqinit() { register int i; diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index ae16decff813..7e5f196dfb09 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -89,7 +89,7 @@ __sysctl(p, uap, retval) int *retval; { int error, dolock = 1; - u_int savelen, oldlen = 0; + u_int savelen = 0, oldlen = 0; sysctlfn *fn; int name[CTL_MAXNAME]; @@ -181,6 +181,7 @@ int securelevel; /* * kernel related system variables. */ +int kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) int *name; u_int namelen; @@ -271,6 +272,7 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) /* * hardware related system variables. */ +int hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) int *name; u_int namelen; @@ -356,6 +358,7 @@ debug_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) * Validate parameters and get old / set new parameters * for an integer-valued sysctl function. */ +int sysctl_int(oldp, oldlenp, newp, newlen, valp) void *oldp; size_t *oldlenp; @@ -380,6 +383,7 @@ sysctl_int(oldp, oldlenp, newp, newlen, valp) /* * As above, but read-only. */ +int sysctl_rdint(oldp, oldlenp, newp, val) void *oldp; size_t *oldlenp; @@ -402,6 +406,7 @@ sysctl_rdint(oldp, oldlenp, newp, val) * Validate parameters and get old / set new parameters * for a string-valued sysctl function. */ +int sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen) void *oldp; size_t *oldlenp; @@ -431,6 +436,7 @@ sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen) /* * As above, but read-only. */ +int sysctl_rdstring(oldp, oldlenp, newp, str) void *oldp; size_t *oldlenp; @@ -454,6 +460,7 @@ sysctl_rdstring(oldp, oldlenp, newp, str) * Validate parameters and get old / set new parameters * for a structure oriented sysctl function. */ +int sysctl_struct(oldp, oldlenp, newp, newlen, sp, len) void *oldp; size_t *oldlenp; @@ -481,6 +488,7 @@ sysctl_struct(oldp, oldlenp, newp, newlen, sp, len) * Validate parameters and get old parameters * for a structure oriented sysctl function. */ +int sysctl_rdstruct(oldp, oldlenp, newp, sp, len) void *oldp; size_t *oldlenp; @@ -502,6 +510,7 @@ sysctl_rdstruct(oldp, oldlenp, newp, sp, len) /* * Get file structures. */ +int sysctl_file(where, sizep) char *where; size_t *sizep; @@ -553,6 +562,7 @@ sysctl_file(where, sizep) */ #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc)) +int sysctl_doproc(name, namelen, where, sizep) int *name; u_int namelen; @@ -718,6 +728,7 @@ struct getkerninfo_args { int arg; }; +int ogetkerninfo(p, uap, retval) struct proc *p; register struct getkerninfo_args *uap; diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index f42900cb75d2..4017e966ee69 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -511,6 +511,7 @@ statclock(frame) /* * Return information about system clocks. */ +int sysctl_clockrate(where, sizep) register char *where; size_t *sizep; diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 4dadcb8e0b9d..2e86376de468 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -42,6 +42,10 @@ #include <machine/cpu.h> +void timevaladd __P((struct timeval *, struct timeval *)); +void timevalsub __P((struct timeval *, struct timeval *)); +void timevalfix __P((struct timeval *)); + /* * Time of day and interval timer support. * @@ -57,6 +61,7 @@ struct gettimeofday_args { struct timezone *tzp; }; /* ARGSUSED */ +int gettimeofday(p, uap, retval) struct proc *p; register struct gettimeofday_args *uap; @@ -82,6 +87,7 @@ struct settimeofday_args { struct timezone *tzp; }; /* ARGSUSED */ +int settimeofday(p, uap, retval) struct proc *p; struct settimeofday_args *uap; @@ -131,6 +137,7 @@ struct adjtime_args { struct timeval *olddelta; }; /* ARGSUSED */ +int adjtime(p, uap, retval) struct proc *p; register struct adjtime_args *uap; @@ -209,6 +216,7 @@ struct getitimer_args { struct itimerval *itv; }; /* ARGSUSED */ +int getitimer(p, uap, retval) struct proc *p; register struct getitimer_args *uap; @@ -246,6 +254,7 @@ struct setitimer_args { struct itimerval *itv, *oitv; }; /* ARGSUSED */ +int setitimer(p, uap, retval) struct proc *p; register struct setitimer_args *uap; @@ -322,6 +331,7 @@ realitexpire(arg) * fix it to have at least minimal value (i.e. if it is less * than the resolution of the clock, round it up.) */ +int itimerfix(tv) struct timeval *tv; { @@ -344,6 +354,7 @@ itimerfix(tv) * that it is called in a context where the timers * on which it is operating cannot change in value. */ +int itimerdecr(itp, usec) register struct itimerval *itp; int usec; @@ -383,6 +394,7 @@ expire: * it just gets very confused in this case. * Caveat emptor. */ +void timevaladd(t1, t2) struct timeval *t1, *t2; { @@ -392,6 +404,7 @@ timevaladd(t1, t2) timevalfix(t1); } +void timevalsub(t1, t2) struct timeval *t1, *t2; { @@ -401,6 +414,7 @@ timevalsub(t1, t2) timevalfix(t1); } +void timevalfix(t1) struct timeval *t1; { diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index f42900cb75d2..4017e966ee69 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -511,6 +511,7 @@ statclock(frame) /* * Return information about system clocks. */ +int sysctl_clockrate(where, sizep) register char *where; size_t *sizep; diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c index 64fac9105d7f..656430d5b104 100644 --- a/sys/kern/kern_xxx.c +++ b/sys/kern/kern_xxx.c @@ -40,11 +40,16 @@ #include <sys/reboot.h> #include <vm/vm.h> #include <sys/sysctl.h> +#include <sys/utsname.h> + +char domainname[MAXHOSTNAMELEN]; +int domainnamelen; struct reboot_args { int opt; }; /* ARGSUSED */ +int reboot(p, uap, retval) struct proc *p; struct reboot_args *uap; @@ -65,6 +70,7 @@ struct gethostname_args { u_int len; }; /* ARGSUSED */ +int ogethostname(p, uap, retval) struct proc *p; struct gethostname_args *uap; @@ -81,6 +87,7 @@ struct sethostname_args { u_int len; }; /* ARGSUSED */ +int osethostname(p, uap, retval) struct proc *p; register struct sethostname_args *uap; @@ -101,6 +108,7 @@ struct gethostid_args { int dummy; }; /* ARGSUSED */ +int ogethostid(p, uap, retval) struct proc *p; struct gethostid_args *uap; @@ -117,6 +125,7 @@ struct sethostid_args { long hostid; }; /* ARGSUSED */ +int osethostid(p, uap, retval) struct proc *p; struct sethostid_args *uap; @@ -130,9 +139,130 @@ osethostid(p, uap, retval) return (0); } +int oquota() { return (ENOSYS); } #endif /* COMPAT_43 */ + +void +shutdown_nice(void) +{ + register struct proc *p; + + /* Send a signal to init(8) and have it shutdown the world */ + p = pfind(1); + psignal(p, SIGINT); + + return; +} + + +struct uname_args { + struct utsname *name; +}; + +/* ARGSUSED */ +int +uname(p, uap, retval) + struct proc *p; + struct uname_args *uap; + int *retval; +{ + int name; + int len; + int rtval; + char *s, *us; + + name = KERN_OSTYPE; + len = sizeof uap->name->sysname; + rtval = kern_sysctl(&name, 1, uap->name->sysname, &len, 0, 0, p); + if( rtval) return rtval; + subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0); + + name = KERN_HOSTNAME; + len = sizeof uap->name->nodename; + rtval = kern_sysctl(&name, 1, uap->name->nodename, &len, 0, 0, p); + if( rtval) return rtval; + subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0); + + name = KERN_OSRELEASE; + len = sizeof uap->name->release; + rtval = kern_sysctl(&name, 1, uap->name->release, &len, 0, 0, p); + if( rtval) return rtval; + subyte( uap->name->release + sizeof(uap->name->release) - 1, 0); + +/* + name = KERN_VERSION; + len = sizeof uap->name->version; + rtval = kern_sysctl(&name, 1, uap->name->version, &len, 0, 0, p); + if( rtval) return rtval; + subyte( uap->name->version + sizeof(uap->name->version) - 1, 0); +*/ + +/* + * this stupid hackery to make the version field look like FreeBSD 1.1 + */ + for(s = version; *s && *s != '#'; s++); + + for(us = uap->name->version; *s && *s != ':'; s++) { + rtval = subyte( us++, *s); + if( rtval) + return rtval; + } + rtval = subyte( us++, 0); + if( rtval) + return rtval; + + name = HW_MACHINE; + len = sizeof uap->name->machine; + rtval = hw_sysctl(&name, 1, uap->name->machine, &len, 0, 0, p); + if( rtval) return rtval; + subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0); + + return 0; +} + +struct getdomainname_args { + char *domainname; + u_int len; +}; + +/* ARGSUSED */ +int +getdomainname(p, uap, retval) + struct proc *p; + struct getdomainname_args *uap; + int *retval; +{ + if (uap->len > domainnamelen + 1) + uap->len = domainnamelen + 1; + return (copyout((caddr_t)domainname, (caddr_t)uap->domainname, uap->len)); +} + +struct setdomainname_args { + char *domainname; + u_int len; +}; + +/* ARGSUSED */ +int +setdomainname(p, uap, retval) + struct proc *p; + struct setdomainname_args *uap; + int *retval; +{ + int error; + + if (error = suser(p->p_ucred, &p->p_acflag)) + return (error); + if (uap->len > sizeof (domainname) - 1) + return EINVAL; + domainnamelen = uap->len; + error = copyin((caddr_t)uap->domainname, domainname, uap->len); + domainname[domainnamelen] = 0; + return (error); +} + diff --git a/sys/kern/subr_clist.c b/sys/kern/subr_clist.c index fe8f000f87d5..acbb7f11cf13 100644 --- a/sys/kern/subr_clist.c +++ b/sys/kern/subr_clist.c @@ -1,159 +1,387 @@ -/*- - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. +/* + * Copyright (C) 1994, David Greenman. This software may be used, modified, + * copied, distributed, and sold, in both source and binary form provided + * that the above copyright and these terms are retained. Under no + * circumstances is the author responsible for the proper functioning + * of this software, nor does the author assume any responsibility + * for damages incurred with its use. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)tty_subr.c 8.2 (Berkeley) 9/5/93 */ #include <sys/param.h> +#include <sys/systm.h> #include <sys/ioctl.h> #include <sys/tty.h> +#include <sys/clist.h> +#include <sys/malloc.h> char cwaiting; -struct cblock *cfree, *cfreelist; -int cfreecount, nclist; +struct cblock *cfreelist = 0; +int cfreecount, nclist = 256; void clist_init() { + int i; + struct cblock *tmp; - /* - * Body deleted. - */ + for (i = 0; i < nclist; ++i) { + tmp = malloc(sizeof(struct cblock), M_TTYS, M_NOWAIT); + if (!tmp) + panic("clist_init: could not allocate cblock"); + bzero((char *)tmp, sizeof(struct cblock)); + tmp->c_next = cfreelist; + cfreelist = tmp; + cfreecount += CBSIZE; + } return; } -getc(a1) - struct clist *a1; +/* + * Get a character from head of clist. + */ +int +getc(clistp) + struct clist *clistp; { + int chr = -1; + int s; + struct cblock *cblockp; - /* - * Body deleted. - */ - return ((char)0); -} + s = spltty(); -q_to_b(a1, a2, a3) - struct clist *a1; - char *a2; - int a3; -{ + /* If there are characters in the list, get one */ + if (clistp->c_cc) { + cblockp = (struct cblock *)((long)clistp->c_cf & ~CROUND); + chr = (u_char)*clistp->c_cf; +#if 0 + /* + * If this char is quoted, set the flag. + */ + if (isset(cblockp->c_quote, clistp->c_cf - (char *)cblockp->c_info)) + chr |= TTY_QUOTE; +#endif + clistp->c_cf++; + clistp->c_cc--; + if ((clistp->c_cf >= (char *)(cblockp+1)) || (clistp->c_cc == 0)) { + if (clistp->c_cc > 0) { + clistp->c_cf = cblockp->c_next->c_info; + } else { + clistp->c_cf = clistp->c_cl = NULL; + } + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + } + } - /* - * Body deleted. - */ - return (0); + splx(s); + return (chr); } -ndqb(a1, a2) - struct clist *a1; - int a2; +/* + * Copy 'amount' of chars, beginning at head of clist 'clistp' to + * destination linear buffer 'dest'. + */ +int +q_to_b(clistp, dest, amount) + struct clist *clistp; + char *dest; + int amount; { + struct cblock *cblockp; + struct cblock *cblockn; + char *dest_orig = dest; + int numc; + int s; - /* - * Body deleted. - */ - return (0); + s = spltty(); + + while (clistp && amount && (clistp->c_cc > 0)) { + cblockp = (struct cblock *)((long)clistp->c_cf & ~CROUND); + cblockn = cblockp + 1; /* pointer arithmetic! */ + numc = min(amount, (char *)cblockn - clistp->c_cf); + numc = min(numc, clistp->c_cc); + bcopy(clistp->c_cf, dest, numc); + amount -= numc; + clistp->c_cf += numc; + clistp->c_cc -= numc; + dest += numc; + if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) { + if (clistp->c_cc > 0) { + clistp->c_cf = cblockp->c_next->c_info; + } else { + clistp->c_cf = clistp->c_cl = NULL; + } + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + } + } + + splx(s); + return (dest - dest_orig); } +/* + * Flush 'amount' of chars, beginning at head of clist 'clistp'. + */ void -ndflush(a1, a2) - struct clist *a1; - int a2; +ndflush(clistp, amount) + struct clist *clistp; + int amount; { + struct cblock *cblockp; + struct cblock *cblockn; + int numc; + int s; - /* - * Body deleted. - */ + s = spltty(); + + while (amount && (clistp->c_cc > 0)) { + cblockp = (struct cblock *)((long)clistp->c_cf & ~CROUND); + cblockn = cblockp + 1; /* pointer arithmetic! */ + numc = min(amount, (char *)cblockn - clistp->c_cf); + numc = min(numc, clistp->c_cc); + amount -= numc; + clistp->c_cf += numc; + clistp->c_cc -= numc; + if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) { + if (clistp->c_cc > 0) { + clistp->c_cf = cblockp->c_next->c_info; + } else { + clistp->c_cf = clistp->c_cl = NULL; + } + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + } + } + + splx(s); return; } -putc(a1, a2) - char a1; - struct clist *a2; +int +putc(chr, clistp) + int chr; + struct clist *clistp; { + struct cblock *cblockp; + struct cblock *bclockn; + int s; - /* - * Body deleted. - */ + s = spltty(); + + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); + + if (clistp->c_cl == NULL) { + if (cfreelist) { + cblockp = cfreelist; + cfreelist = cfreelist->c_next; + cfreecount -= CBSIZE; + cblockp->c_next = NULL; + clistp->c_cf = clistp->c_cl = cblockp->c_info; + clistp->c_cc = 0; + } else { + splx(s); + return (-1); + } + } else { + if (((long)clistp->c_cl & CROUND) == 0) { + if (cfreelist) { + cblockp = (cblockp-1)->c_next = cfreelist; + cfreelist = cfreelist->c_next; + cfreecount -= CBSIZE; + cblockp->c_next = NULL; + clistp->c_cl = cblockp->c_info; + } else { + splx(s); + return (-1); + } + } + } + +#if 0 + if (chr & TTY_QUOTE) + setbit(cblockp->c_quote, clistp->c_cl - (char *)cblockp->c_info); +#endif + *clistp->c_cl++ = chr; + clistp->c_cc++; + + splx(s); return (0); } -b_to_q(a1, a2, a3) - char *a1; - int a2; - struct clist *a3; +/* + * Copy data from linear buffer to clist chain. + */ +int +b_to_q(src, amount, clistp) + char *src; + int amount; + struct clist *clistp; { + struct cblock *cblockp; + struct cblock *bclockn; + int s; + int numc; + + s = spltty(); /* - * Body deleted. + * If there are no cblocks assigned to this clist yet, + * then get one. */ - return (0); + if (clistp->c_cl == NULL) { + if (cfreelist) { + cblockp = cfreelist; + cfreelist = cfreelist->c_next; + cfreecount -= CBSIZE; + cblockp->c_next = NULL; + clistp->c_cf = clistp->c_cl = cblockp->c_info; + clistp->c_cc = 0; + } else { + splx(s); + return (amount); + } + } else { + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); + } + + while (amount) { + /* + * Get another cblock if needed. + */ + if (((long)clistp->c_cl & CROUND) == 0) { + if (cfreelist) { + cblockp = (cblockp-1)->c_next = cfreelist; + cfreelist = cfreelist->c_next; + cfreecount -= CBSIZE; + cblockp->c_next = NULL; + clistp->c_cl = cblockp->c_info; + } else { + splx(s); + return (amount); + } + } + + /* + * Copy a chunk of the linear buffer up to the end + * of this cblock. + */ + cblockp += 1; + numc = min(amount, (char *)(cblockp) - clistp->c_cl); + bcopy(src, clistp->c_cl, numc); + + /* + * Clear quote bits. + */ + + /* + * ...and update pointer for the next chunk. + */ + src += numc; + clistp->c_cl += numc; + clistp->c_cc += numc; + amount -= numc; + } + + splx(s); + return (amount); } char * -nextc(a1, a2, a3) - struct clist *a1; - char *a2; - int *a3; +nextc(clistp, cp, dst) + struct clist *clistp; + char *cp; + int *dst; { + struct cblock *cblockp; - /* - * Body deleted. - */ - return ((char *)0); + ++cp; + if (clistp->c_cc && (cp != clistp->c_cl)) { + if (((long)cp & CROUND) == 0) + cp = ((struct cblock *)cp - 1)->c_next->c_info; + cblockp = (struct cblock *)((long)cp & ~CROUND); +#if 0 + *dst = *cp | (isset(cblockp->c_quote, cp - (char *)cblockp->c_info) ? TTY_QUOTE : 0); +#endif + *dst = (u_char)*cp; + return (cp); + } + + return (NULL); } -unputc(a1) - struct clist *a1; +int +unputc(clistp) + struct clist *clistp; { + struct cblock *cblockp = 0, *cbp = 0; + int s; + int chr = -1; + + + s = spltty(); + + if (clistp->c_cc) { + --clistp->c_cc; + chr = (u_char)*--clistp->c_cl; + /* + * Get the quote flag and 'unput' it, too. + */ + + /* XXX write me! */ + + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); + + /* + * If all of the characters have been unput in this + * cblock, the find the previous one and free this + * one. + */ + if (clistp->c_cc && (clistp->c_cl <= (char *)cblockp->c_info)) { + cbp = (struct cblock *)((long)clistp->c_cf & ~CROUND); + + while (cbp->c_next != cblockp) + cbp = cbp->c_next; + + clistp->c_cl = (char *)(cbp+1); + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + cbp->c_next = NULL; + } + } /* - * Body deleted. + * If there are no more characters on the list, then + * free the last cblock. */ - return ((char)0); + if ((clistp->c_cc == 0) && clistp->c_cl) { + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + clistp->c_cf = clistp->c_cl = NULL; + } + + splx(s); + return (chr); } void -catq(a1, a2) - struct clist *a1, *a2; +catq(src_clistp, dest_clistp) + struct clist *src_clistp, *dest_clistp; { + char buffer[CBSIZE*2]; + int amount; + + while (src_clistp->c_cc) { + amount = q_to_b(src_clistp, buffer, sizeof(buffer)); + b_to_q(buffer, amount, dest_clistp); + } - /* - * Body deleted. - */ return; } diff --git a/sys/kern/subr_disklabel.c b/sys/kern/subr_disklabel.c index 78dede4da773..cc0f28d37f15 100644 --- a/sys/kern/subr_disklabel.c +++ b/sys/kern/subr_disklabel.c @@ -43,6 +43,7 @@ #include <sys/buf.h> #include <sys/disklabel.h> #include <sys/syslog.h> +#include <sys/dkbad.h> /* * Seek sort for disks. We depend on the driver which calls us using b_resid @@ -153,14 +154,19 @@ insert: bp->b_actf = bq->b_actf; * string on failure. */ char * -readdisklabel(dev, strat, lp) +readdisklabel(dev, strat, lp, dp, bdp) dev_t dev; int (*strat)(); register struct disklabel *lp; + struct dos_partition *dp; + struct dkbad *bdp; { register struct buf *bp; struct disklabel *dlp; char *msg = NULL; + int dospartoff; + int i; + int cyl; if (lp->d_secperunit == 0) lp->d_secperunit = 0x1fffffff; @@ -170,11 +176,61 @@ readdisklabel(dev, strat, lp) lp->d_partitions[0].p_offset = 0; bp = geteblk((int)lp->d_secsize); - bp->b_dev = dev; - bp->b_blkno = LABELSECTOR; + /* do dos partitions in the process of getting disklabel? */ + dospartoff = 0; + cyl = LABELSECTOR / lp->d_secpercyl; + if (dp) { + struct dos_partition *ap; + + /* read master boot record */ + bp->b_dev = dev; + bp->b_blkno = DOSBBSECTOR; + bp->b_bcount = lp->d_secsize; + bp->b_flags = B_BUSY | B_READ; + bp->b_cylinder = DOSBBSECTOR / lp->d_secpercyl; + (*strat)(bp); + + /* if successful, wander through dos partition table */ + if (biowait(bp)) { + msg = "dos partition I/O error"; + goto done; + } else { + /* XXX how do we check veracity/bounds of this? */ + bcopy(bp->b_un.b_addr + DOSPARTOFF, dp, + NDOSPART * sizeof(*dp)); + for (i = 0; i < NDOSPART; i++, dp++) + /* is this ours? */ + if (dp->dp_size && + dp->dp_typ == DOSPTYP_386BSD + && dospartoff == 0) { + + /* need sector address for SCSI/IDE, + cylinder for ESDI/ST506/RLL */ + dospartoff = dp->dp_start; + cyl = DPCYL(dp->dp_scyl, dp->dp_ssect); + + /* update disklabel with details */ + lp->d_partitions[0].p_size = + dp->dp_size; + lp->d_partitions[0].p_offset = + dp->dp_start; + lp->d_ntracks = dp->dp_ehd + 1; + lp->d_nsectors = DPSECT(dp->dp_esect); + lp->d_subtype |= (lp->d_subtype & 3) + + i | DSTYPE_INDOSPART; + lp->d_secpercyl = lp->d_ntracks * + lp->d_nsectors; + } + } + + } + + /* next, dig out disk label */ + bp->b_blkno = dospartoff + LABELSECTOR; + bp->b_dev = dev; bp->b_bcount = lp->d_secsize; bp->b_flags = B_BUSY | B_READ; - bp->b_cylinder = LABELSECTOR / lp->d_secpercyl; + bp->b_cylinder = cyl; (*strat)(bp); if (biowait(bp)) msg = "I/O error"; @@ -194,6 +250,46 @@ readdisklabel(dev, strat, lp) break; } } + if (msg) + goto done; + + /* obtain bad sector table if requested and present */ + if (bdp && (lp->d_flags & D_BADSECT)) { + struct dkbad *db; + + printf("d_secsize: %d\n", lp->d_secsize); + i = 0; + do { + /* read a bad sector table */ + bp->b_flags = B_BUSY | B_READ; + bp->b_blkno = lp->d_secperunit - lp->d_nsectors + i; + if (lp->d_secsize > DEV_BSIZE) + bp->b_blkno *= lp->d_secsize / DEV_BSIZE; + else + bp->b_blkno /= DEV_BSIZE / lp->d_secsize; + bp->b_bcount = lp->d_secsize; + bp->b_cylinder = lp->d_ncylinders - 1; + (*strat)(bp); + + /* if successful, validate, otherwise try another */ + if (biowait(bp)) { + msg = "bad sector table I/O error"; + } else { + db = (struct dkbad *)(bp->b_un.b_addr); +#define DKBAD_MAGIC 0x4321 + if (db->bt_mbz == 0 + && db->bt_flag == DKBAD_MAGIC) { + msg = NULL; + *bdp = *db; + break; + } else + msg = "bad sector table corrupted"; + } + } while ((bp->b_flags & B_ERROR) && (i += 2) < 10 && + i < lp->d_nsectors); + } + +done: bp->b_flags = B_INVAL | B_AGE; brelse(bp); return (msg); @@ -294,6 +390,7 @@ done: /* * Compute checksum for disk label. */ +int dkcksum(lp) register struct disklabel *lp; { diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c index f065761d756e..92e4543f38db 100644 --- a/sys/kern/subr_log.c +++ b/sys/kern/subr_log.c @@ -59,6 +59,7 @@ struct logsoftc { int log_open; /* also used in log() */ /*ARGSUSED*/ +int logopen(dev, flags, mode, p) dev_t dev; int flags, mode; @@ -87,6 +88,7 @@ logopen(dev, flags, mode, p) } /*ARGSUSED*/ +int logclose(dev, flag, mode, p) dev_t dev; int flag, mode; @@ -99,6 +101,7 @@ logclose(dev, flag, mode, p) } /*ARGSUSED*/ +int logread(dev, uio, flag) dev_t dev; struct uio *uio; @@ -144,6 +147,7 @@ logread(dev, uio, flag) } /*ARGSUSED*/ +int logselect(dev, rw, p) dev_t dev; int rw; @@ -165,6 +169,7 @@ logselect(dev, rw, p) return (0); } +void logwakeup() { struct proc *p; @@ -185,6 +190,7 @@ logwakeup() } /*ARGSUSED*/ +int logioctl(dev, com, data, flag, p) dev_t dev; int com; diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c index 9f4e2cae857c..c871594221de 100644 --- a/sys/kern/subr_param.c +++ b/sys/kern/subr_param.c @@ -75,7 +75,8 @@ int tickadj = 30000 / (60 * HZ); /* can adjust 30ms in 60s */ struct timezone tz = { TIMEZONE, DST }; #define NPROC (20 + 16 * MAXUSERS) int maxproc = NPROC; -#define NTEXT (80 + NPROC / 8) /* actually the object cache */ +#define NTEXT NPROC +int vm_cache_max = NTEXT/2 + 16; #define NVNODE (NPROC + NTEXT + 100) int desiredvnodes = NVNODE; int maxfiles = 3 * (NPROC + MAXUSERS) + 80; diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index 2adb7793a3c5..5ef4925856f2 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -122,6 +122,10 @@ panic(fmt, va_alist) if (boothowto & RB_KDB) kdbpanic(); #endif +#include "ddb.h" +#if NDDB > 0 + Debugger ("panic"); +#endif boot(bootopt); } @@ -508,8 +512,10 @@ putchar(c, flags, tp) * Scaled down version of sprintf(3). */ #ifdef __STDC__ +int sprintf(char *buf, const char *cfmt, ...) #else +int sprintf(buf, cfmt, va_alist) char *buf, *cfmt; #endif diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index 4fb81d823cac..efe56b098d23 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -146,6 +146,7 @@ struct profil_args { u_int scale; }; /* ARGSUSED */ +int profil(p, uap, retval) struct proc *p; register struct profil_args *uap; diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 9bb38e1e60d3..382416f06e3f 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -41,32 +41,33 @@ * 386 Trap and System call handleing */ -#include "isa.h" -#include "npx.h" -#include "ddb.h" -#include "machine/cpu.h" -#include "machine/psl.h" -#include "machine/reg.h" -#include "machine/eflags.h" - -#include "param.h" -#include "systm.h" -#include "proc.h" -#include "user.h" -#include "acct.h" -#include "kernel.h" +#include <sys/param.h> +#include <sys/systm.h> + +#include <sys/proc.h> +#include <sys/user.h> +#include <sys/acct.h> +#include <sys/kernel.h> +#include <sys/syscall.h> #ifdef KTRACE -#include "ktrace.h" +#include <sys/ktrace.h> #endif -#include "vm/vm_param.h" -#include "vm/pmap.h" -#include "vm/vm_map.h" -#include "vm/vm_user.h" -#include "vm/vm_page.h" -#include "sys/vmmeter.h" +#include <vm/vm_param.h> +#include <vm/pmap.h> +#include <vm/vm_map.h> +#include <vm/vm_page.h> + +#include <machine/cpu.h> +#include <machine/psl.h> +#include <machine/reg.h> +#include <machine/eflags.h> + +#include <machine/trap.h> -#include "machine/trap.h" +#include "isa.h" +#include "npx.h" +#include "ddb.h" #ifdef __GNUC__ @@ -84,7 +85,7 @@ void write_gs __P((/* promoted u_short */ int gs)); #endif /* __GNUC__ */ -extern int grow(struct proc *,int); +extern int grow(struct proc *,u_int); struct sysent sysent[]; int nsysent; @@ -139,7 +140,7 @@ trap(frame) { register int i; register struct proc *p = curproc; - struct timeval syst; + u_quad_t sticks = 0; int ucode, type, code, eva, fault_type; frame.tf_eflags &= ~PSL_NT; /* clear nested trap XXX */ @@ -177,10 +178,10 @@ copyfault: return; } - syst = p->p_stime; if (ISPL(frame.tf_cs) == SEL_UPL) { type |= T_USER; - p->p_regs = (int *)&frame; + p->p_md.md_regs = (int *)&frame; + sticks = p->p_sticks; } skiptoswitch: @@ -210,9 +211,9 @@ skiptoswitch: case T_ASTFLT|T_USER: /* Allow process switch */ astoff(); cnt.v_soft++; - if ((p->p_flag & SOWEUPC) && p->p_stats->p_prof.pr_scale) { + if ((p->p_flag & P_OWEUPC) && p->p_stats->p_prof.pr_scale) { addupc(frame.tf_eip, &p->p_stats->p_prof, 1); - p->p_flag &= ~SOWEUPC; + p->p_flag &= ~P_OWEUPC; } goto out; @@ -284,7 +285,6 @@ skiptoswitch: else ftype = VM_PROT_READ; - oldflags = p->p_flag; if (map != kernel_map) { vm_offset_t pa; vm_offset_t v = (vm_offset_t) vtopte(va); @@ -294,7 +294,7 @@ skiptoswitch: * Keep swapout from messing with us during this * critical time. */ - p->p_flag |= SLOCK; + ++p->p_lock; /* * Grow the stack if necessary @@ -303,8 +303,7 @@ skiptoswitch: && (caddr_t)va < (caddr_t)USRSTACK) { if (!grow(p, va)) { rv = KERN_FAILURE; - p->p_flag &= ~SLOCK; - p->p_flag |= (oldflags & SLOCK); + --p->p_lock; goto nogo; } } @@ -332,13 +331,10 @@ skiptoswitch: if( ptepg->hold_count == 0 && ptepg->wire_count == 0) { pmap_page_protect( VM_PAGE_TO_PHYS(ptepg), VM_PROT_NONE); - if( ptepg->flags & PG_CLEAN) - vm_page_free(ptepg); + vm_page_free(ptepg); } - - p->p_flag &= ~SLOCK; - p->p_flag |= (oldflags & SLOCK); + --p->p_lock; } else { /* * Since we know that kernel virtual address addresses @@ -482,32 +478,29 @@ nogo: out: while (i = CURSIG(p)) - psig(i); - p->p_pri = p->p_usrpri; + postsig(i); + p->p_priority = p->p_usrpri; if (want_resched) { int s; /* * Since we are curproc, clock will normally just change * our priority without moving us from one queue to another * (since the running process is not on a queue.) - * If that happened after we setrq ourselves but before we - * swtch()'ed, we might not be on the queue indicated by + * If that happened after we setrunqueue ourselves but before we + * mi_switch()'ed, we might not be on the queue indicated by * our priority. */ s = splclock(); - setrq(p); + setrunqueue(p); p->p_stats->p_ru.ru_nivcsw++; - swtch(); + mi_switch(); splx(s); while (i = CURSIG(p)) - psig(i); + postsig(i); } if (p->p_stats->p_prof.pr_scale) { - int ticks; - struct timeval *tv = &p->p_stime; + u_quad_t ticks = p->p_sticks - sticks; - ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + - (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); if (ticks) { #ifdef PROFTIMER extern int profscale; @@ -518,7 +511,7 @@ out: #endif } } - curpri = p->p_pri; + curpriority = p->p_priority; } /* @@ -546,14 +539,12 @@ int trapwrite(addr) p = curproc; vm = p->p_vmspace; - oldflags = p->p_flag; - p->p_flag |= SLOCK; + ++p->p_lock; if ((caddr_t)va >= vm->vm_maxsaddr && (caddr_t)va < (caddr_t)USRSTACK) { if (!grow(p, va)) { - p->p_flag &= ~SLOCK; - p->p_flag |= (oldflags & SLOCK); + --p->p_lock; return (1); } } @@ -579,8 +570,7 @@ int trapwrite(addr) vm_map_pageable(&vm->vm_map, v, round_page(v+1), TRUE); } - p->p_flag &= ~SLOCK; - p->p_flag |= (oldflags & SLOCK); + --p->p_lock; if (rv != KERN_SUCCESS) return 1; @@ -603,31 +593,45 @@ syscall(frame) register int i; register struct sysent *callp; register struct proc *p = curproc; - struct timeval syst; + u_quad_t sticks; int error, opc; int args[8], rval[2]; - int code; + u_int code; #ifdef lint r0 = 0; r0 = r0; r1 = 0; r1 = r1; #endif - syst = p->p_stime; + sticks = p->p_sticks; if (ISPL(frame.tf_cs) != SEL_UPL) panic("syscall"); code = frame.tf_eax; - p->p_regs = (int *)&frame; + p->p_md.md_regs = (int *)&frame; params = (caddr_t)frame.tf_esp + sizeof (int) ; /* * Reconstruct pc, assuming lcall $X,y is 7 bytes, as it is always. */ opc = frame.tf_eip - 7; - if (code == 0) { + /* + * Need to check if this is a 32 bit or 64 bit syscall. + */ + if (code == SYS_syscall) { + /* + * Code is first argument, followed by actual args. + */ code = fuword(params); params += sizeof (int); + } else if (code == SYS___syscall) { + /* + * Like syscall, but code is a quad, so as to maintain + * quad alignment for the rest of the arguments. + */ + code = fuword(params + _QUAD_LOWWORD * sizeof(int)); + params += sizeof(quad_t); } - if (code < 0 || code >= nsysent) + + if (code >= nsysent) callp = &sysent[0]; else callp = &sysent[code]; @@ -672,32 +676,29 @@ done: */ p = curproc; while (i = CURSIG(p)) - psig(i); - p->p_pri = p->p_usrpri; + postsig(i); + p->p_priority = p->p_usrpri; if (want_resched) { int s; /* * Since we are curproc, clock will normally just change * our priority without moving us from one queue to another * (since the running process is not on a queue.) - * If that happened after we setrq ourselves but before we + * If that happened after we setrunqueue ourselves but before we * swtch()'ed, we might not be on the queue indicated by * our priority. */ s = splclock(); - setrq(p); + setrunqueue(p); p->p_stats->p_ru.ru_nivcsw++; - swtch(); + mi_switch(); splx(s); while (i = CURSIG(p)) - psig(i); + postsig(i); } if (p->p_stats->p_prof.pr_scale) { - int ticks; - struct timeval *tv = &p->p_stime; + u_quad_t ticks = p->p_sticks - sticks; - ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + - (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); if (ticks) { #ifdef PROFTIMER extern int profscale; @@ -708,21 +709,9 @@ done: #endif } } - curpri = p->p_pri; + curpriority = p->p_priority; #ifdef KTRACE if (KTRPOINT(p, KTR_SYSRET)) ktrsysret(p->p_tracep, code, error, rval[0]); #endif -#ifdef DIAGNOSTICx -{ extern int _udatasel, _ucodesel; - if (frame.tf_ss != _udatasel) - printf("ss %x call %d\n", frame.tf_ss, code); - if ((frame.tf_cs&0xffff) != _ucodesel) - printf("cs %x call %d\n", frame.tf_cs, code); - if (frame.tf_eip > VM_MAXUSER_ADDRESS) { - printf("eip %x call %d\n", frame.tf_eip, code); - frame.tf_eip = 0; - } -} -#endif } diff --git a/sys/kern/subr_xxx.c b/sys/kern/subr_xxx.c index c692ec11a3bd..3304d57da6e8 100644 --- a/sys/kern/subr_xxx.c +++ b/sys/kern/subr_xxx.c @@ -45,6 +45,7 @@ /* * Unsupported device function (e.g. writing to read-only device). */ +int enodev() { @@ -54,6 +55,7 @@ enodev() /* * Unconfigured device function; driver not configured. */ +int enxio() { @@ -63,6 +65,7 @@ enxio() /* * Unsupported ioctl function. */ +int enoioctl() { @@ -74,6 +77,7 @@ enoioctl() * This is used for an otherwise-reasonable operation * that is not supported by the current system binary. */ +int enosys() { @@ -84,6 +88,7 @@ enosys() * Return error for operation not supported * on a specific object or file type. */ +int eopnotsupp() { @@ -93,6 +98,7 @@ eopnotsupp() /* * Generic null operation, always returns success. */ +int nullop() { diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index a121209f9fef..919c8664c5d9 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -62,6 +62,7 @@ struct read_args { u_int nbyte; }; /* ARGSUSED */ +int read(p, uap, retval) struct proc *p; register struct read_args *uap; @@ -117,6 +118,7 @@ struct readv_args { struct iovec *iovp; u_int iovcnt; }; +int readv(p, uap, retval) struct proc *p; register struct readv_args *uap; @@ -158,10 +160,6 @@ readv(p, uap, retval) goto done; auio.uio_resid = 0; for (i = 0; i < uap->iovcnt; i++) { - if (iov->iov_len < 0) { - error = EINVAL; - goto done; - } auio.uio_resid += iov->iov_len; if (auio.uio_resid < 0) { error = EINVAL; @@ -207,6 +205,7 @@ struct write_args { char *buf; u_int nbyte; }; +int write(p, uap, retval) struct proc *p; register struct write_args *uap; @@ -217,6 +216,7 @@ write(p, uap, retval) struct uio auio; struct iovec aiov; long cnt, error = 0; + int i; #ifdef KTRACE struct iovec ktriov; #endif @@ -266,6 +266,7 @@ struct writev_args { struct iovec *iovp; u_int iovcnt; }; +int writev(p, uap, retval) struct proc *p; register struct writev_args *uap; @@ -307,10 +308,6 @@ writev(p, uap, retval) goto done; auio.uio_resid = 0; for (i = 0; i < uap->iovcnt; i++) { - if (iov->iov_len < 0) { - error = EINVAL; - goto done; - } auio.uio_resid += iov->iov_len; if (auio.uio_resid < 0) { error = EINVAL; @@ -360,6 +357,7 @@ struct ioctl_args { caddr_t data; }; /* ARGSUSED */ +int ioctl(p, uap, retval) struct proc *p; register struct ioctl_args *uap; @@ -497,6 +495,7 @@ struct select_args { fd_set *in, *ou, *ex; struct timeval *tv; }; +int select(p, uap, retval) register struct proc *p; register struct select_args *uap; @@ -588,6 +587,7 @@ done: return (error); } +int selscan(p, ibits, obits, nfd, retval) struct proc *p; fd_set *ibits, *obits; @@ -620,6 +620,7 @@ selscan(p, ibits, obits, nfd, retval) } /*ARGSUSED*/ +int seltrue(dev, flag, p) dev_t dev; int flag; diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 4cc40baf5821..527371df71bb 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -51,6 +51,7 @@ struct ptrace_args { caddr_t addr; int data; }; +int ptrace(a1, a2, a3) struct proc *a1; struct ptrace_args *a2; @@ -63,6 +64,7 @@ ptrace(a1, a2, a3) return (ENOSYS); } +int trace_req(a1) struct proc *a1; { diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index a93ae86df853..63f529841170 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -51,6 +51,7 @@ struct fileops socketops = { soo_read, soo_write, soo_ioctl, soo_select, soo_close }; /* ARGSUSED */ +int soo_read(fp, uio, cred) struct file *fp; struct uio *uio; @@ -62,6 +63,7 @@ soo_read(fp, uio, cred) } /* ARGSUSED */ +int soo_write(fp, uio, cred) struct file *fp; struct uio *uio; @@ -72,6 +74,7 @@ soo_write(fp, uio, cred) uio, (struct mbuf *)0, (struct mbuf *)0, 0)); } +int soo_ioctl(fp, cmd, data, p) struct file *fp; int cmd; @@ -130,6 +133,7 @@ soo_ioctl(fp, cmd, data, p) (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); } +int soo_select(fp, which, p) struct file *fp; int which; @@ -171,6 +175,7 @@ soo_select(fp, which, p) return (0); } +int soo_stat(so, ub) register struct socket *so; register struct stat *ub; @@ -184,6 +189,7 @@ soo_stat(so, ub) } /* ARGSUSED */ +int soo_close(fp, p) struct file *fp; struct proc *p; diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 1809905a4f6a..339b9979a1fa 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -188,10 +188,10 @@ char *syscallnames[] = { #else "#161", /* 161 = nosys */ #endif - "#162", /* 162 = nosys */ - "#163", /* 163 = nosys */ - "#164", /* 164 = nosys */ - "#165", /* 165 = nosys */ + "getdomainname", /* 162 = getdomainname */ + "setdomainname", /* 163 = setdomainname */ + "uname", /* 164 = uname */ + "sysarch", /* 165 = sysarch */ "#166", /* 166 = nosys */ "#167", /* 167 = nosys */ "#168", /* 168 = nosys */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 1b8de145fba7..4ba7df2ba2f0 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -100,7 +100,7 @@ 68 OBSOL 0 vwrite 69 STD 1 sbrk 70 STD 1 sstk -71 COMPAT 7 mmap +71 COMPAT 6 mmap 72 STD 1 ovadvise vadvise 73 STD 2 munmap 74 STD 3 mprotect @@ -212,10 +212,10 @@ #else 161 UNIMPL 0 nosys #endif -162 UNIMPL 0 nosys -163 UNIMPL 0 nosys -164 UNIMPL 0 nosys -165 UNIMPL 0 nosys +162 STD 2 getdomainname +163 STD 2 setdomainname +164 STD 1 uname +165 STD 2 sysarch 166 UNIMPL 0 nosys 167 UNIMPL 0 nosys 168 UNIMPL 0 nosys diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 6cc7be23700f..23309a3a7f6b 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1355,7 +1355,7 @@ ttwrite(tp, uio, flag) register struct uio *uio; int flag; { - register char *cp; + register char *cp = 0; register int cc, ce; register struct proc *p; int i, hiwat, cnt, error, s; diff --git a/sys/kern/tty_compat.c b/sys/kern/tty_compat.c index a6a39d9d7bf3..7047230844d9 100644 --- a/sys/kern/tty_compat.c +++ b/sys/kern/tty_compat.c @@ -49,6 +49,9 @@ #include <sys/kernel.h> #include <sys/syslog.h> +void ttcompatsetflags __P((struct tty *, struct termios *)); +void ttcompatsetlflags __P((struct tty *, struct termios *)); + int ttydebug = 0; static struct speedtab compatspeeds[] = { @@ -76,6 +79,7 @@ static int compatspcodes[16] = { }; /*ARGSUSED*/ +int ttcompat(tp, com, data, flag) register struct tty *tp; int com; @@ -222,6 +226,7 @@ ttcompat(tp, com, data, flag) return (0); } +int ttcompatgetflags(tp) register struct tty *tp; { @@ -279,6 +284,7 @@ if (ttydebug) return (flags); } +void ttcompatsetflags(tp, t) register struct tty *tp; register struct termios *t; @@ -350,6 +356,7 @@ ttcompatsetflags(tp, t) t->c_cflag = cflag; } +void ttcompatsetlflags(tp, t) register struct tty *tp; register struct termios *t; diff --git a/sys/kern/tty_conf.c b/sys/kern/tty_conf.c index b53edb429756..f517a37f0ed0 100644 --- a/sys/kern/tty_conf.c +++ b/sys/kern/tty_conf.c @@ -84,8 +84,13 @@ struct linesw linesw[] = { ttynodisc, ttyerrclose, ttyerrio, ttyerrio, nullioctl, ttyerrinput, ttyerrstart, nullmodem }, /* 1- defunct */ +#ifdef COMPAT_43 + { ttyopen, ttylclose, ttread, ttwrite, nullioctl, + ttyinput, ttstart, ttymodem }, /* 2- NTTYDISC */ +#else { ttynodisc, ttyerrclose, ttyerrio, ttyerrio, nullioctl, - ttyerrinput, ttyerrstart, nullmodem }, /* 2- defunct */ + ttyerrinput, ttyerrstart, nullmodem }, +#endif #if NTB > 0 { tbopen, tbclose, tbread, enodev, tbioctl, @@ -111,6 +116,7 @@ int nlinesw = sizeof (linesw) / sizeof (linesw[0]); * discipline specific ioctl command. */ /*ARGSUSED*/ +int nullioctl(tp, cmd, data, flags, p) struct tty *tp; int cmd; diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c index f5fc887be1b1..ceb4b398b62c 100644 --- a/sys/kern/tty_cons.c +++ b/sys/kern/tty_cons.c @@ -41,9 +41,9 @@ #include "sys/param.h" +#include <sys/systm.h> #include "sys/proc.h" #include "sys/user.h" -#include "sys/systm.h" #include "sys/buf.h" #include "sys/ioctl.h" #include "sys/tty.h" @@ -122,7 +122,7 @@ cnopen(dev, flag, mode, p) return (0); dev = cn_tab->cn_dev; - if ((vfinddev(dev, VCHR, &vp) == 0) && vcount(vp)) + if (vfinddev(dev, VCHR, &vp) && vcount(vp)) return (0); return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p)); @@ -140,7 +140,7 @@ cnclose(dev, flag, mode, p) return (0); dev = cn_tab->cn_dev; - if ((vfinddev(dev, VCHR, &vp) == 0) && vcount(vp)) + if (vfinddev(dev, VCHR, &vp) && vcount(vp)) return (0); return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p)); diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index 0e6911b63e19..50f0581f7612 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -76,7 +76,8 @@ int npty = NPTY; /* for pstat -t */ #define PF_NOSTOP 0x40 #define PF_UCNTL 0x80 /* user control mode */ -void ptsstop __P((struct tty *, int)); +void ptsstop __P((struct tty *, int)); +void ptcwakeup __P((struct tty *, int)); /* * Establish n (or default if n is 1) ptys in the system. @@ -106,6 +107,7 @@ ptyattach(n) } /*ARGSUSED*/ +int ptsopen(dev, flag, devtype, p) dev_t dev; int flag, devtype; @@ -143,6 +145,7 @@ ptsopen(dev, flag, devtype, p) return (error); } +int ptsclose(dev, flag, mode, p) dev_t dev; int flag, mode; @@ -158,6 +161,7 @@ ptsclose(dev, flag, mode, p) return (err); } +int ptsread(dev, uio, flag) dev_t dev; struct uio *uio; @@ -210,6 +214,7 @@ again: * Wakeups of controlling tty will happen * indirectly, when tty driver calls ptsstart. */ +int ptswrite(dev, uio, flag) dev_t dev; struct uio *uio; @@ -242,6 +247,7 @@ ptsstart(tp) ptcwakeup(tp, FREAD); } +void ptcwakeup(tp, flag) struct tty *tp; int flag; @@ -260,8 +266,10 @@ ptcwakeup(tp, flag) /*ARGSUSED*/ #ifdef __STDC__ +int ptcopen(dev_t dev, int flag, int devtype, struct proc *p) #else +int ptcopen(dev, flag, devtype, p) dev_t dev; int flag, devtype; @@ -289,6 +297,7 @@ ptcopen(dev, flag, devtype, p) return (0); } +int ptcclose(dev) dev_t dev; { @@ -302,6 +311,7 @@ ptcclose(dev) return (0); } +int ptcread(dev, uio, flag) dev_t dev; struct uio *uio; @@ -392,6 +402,7 @@ ptsstop(tp, flush) ptcwakeup(tp, flag); } +int ptcselect(dev, rw, p) dev_t dev; int rw; @@ -446,13 +457,14 @@ ptcselect(dev, rw, p) return (0); } +int ptcwrite(dev, uio, flag) dev_t dev; register struct uio *uio; int flag; { register struct tty *tp = &pt_tty[minor(dev)]; - register u_char *cp; + register u_char *cp = 0; register int cc = 0; u_char locbuf[BUFSIZ]; int cnt = 0; @@ -534,6 +546,7 @@ block: } /*ARGSUSED*/ +int ptyioctl(dev, cmd, data, flag, p) dev_t dev; int cmd; diff --git a/sys/kern/tty_subr.c b/sys/kern/tty_subr.c index fe8f000f87d5..acbb7f11cf13 100644 --- a/sys/kern/tty_subr.c +++ b/sys/kern/tty_subr.c @@ -1,159 +1,387 @@ -/*- - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. +/* + * Copyright (C) 1994, David Greenman. This software may be used, modified, + * copied, distributed, and sold, in both source and binary form provided + * that the above copyright and these terms are retained. Under no + * circumstances is the author responsible for the proper functioning + * of this software, nor does the author assume any responsibility + * for damages incurred with its use. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)tty_subr.c 8.2 (Berkeley) 9/5/93 */ #include <sys/param.h> +#include <sys/systm.h> #include <sys/ioctl.h> #include <sys/tty.h> +#include <sys/clist.h> +#include <sys/malloc.h> char cwaiting; -struct cblock *cfree, *cfreelist; -int cfreecount, nclist; +struct cblock *cfreelist = 0; +int cfreecount, nclist = 256; void clist_init() { + int i; + struct cblock *tmp; - /* - * Body deleted. - */ + for (i = 0; i < nclist; ++i) { + tmp = malloc(sizeof(struct cblock), M_TTYS, M_NOWAIT); + if (!tmp) + panic("clist_init: could not allocate cblock"); + bzero((char *)tmp, sizeof(struct cblock)); + tmp->c_next = cfreelist; + cfreelist = tmp; + cfreecount += CBSIZE; + } return; } -getc(a1) - struct clist *a1; +/* + * Get a character from head of clist. + */ +int +getc(clistp) + struct clist *clistp; { + int chr = -1; + int s; + struct cblock *cblockp; - /* - * Body deleted. - */ - return ((char)0); -} + s = spltty(); -q_to_b(a1, a2, a3) - struct clist *a1; - char *a2; - int a3; -{ + /* If there are characters in the list, get one */ + if (clistp->c_cc) { + cblockp = (struct cblock *)((long)clistp->c_cf & ~CROUND); + chr = (u_char)*clistp->c_cf; +#if 0 + /* + * If this char is quoted, set the flag. + */ + if (isset(cblockp->c_quote, clistp->c_cf - (char *)cblockp->c_info)) + chr |= TTY_QUOTE; +#endif + clistp->c_cf++; + clistp->c_cc--; + if ((clistp->c_cf >= (char *)(cblockp+1)) || (clistp->c_cc == 0)) { + if (clistp->c_cc > 0) { + clistp->c_cf = cblockp->c_next->c_info; + } else { + clistp->c_cf = clistp->c_cl = NULL; + } + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + } + } - /* - * Body deleted. - */ - return (0); + splx(s); + return (chr); } -ndqb(a1, a2) - struct clist *a1; - int a2; +/* + * Copy 'amount' of chars, beginning at head of clist 'clistp' to + * destination linear buffer 'dest'. + */ +int +q_to_b(clistp, dest, amount) + struct clist *clistp; + char *dest; + int amount; { + struct cblock *cblockp; + struct cblock *cblockn; + char *dest_orig = dest; + int numc; + int s; - /* - * Body deleted. - */ - return (0); + s = spltty(); + + while (clistp && amount && (clistp->c_cc > 0)) { + cblockp = (struct cblock *)((long)clistp->c_cf & ~CROUND); + cblockn = cblockp + 1; /* pointer arithmetic! */ + numc = min(amount, (char *)cblockn - clistp->c_cf); + numc = min(numc, clistp->c_cc); + bcopy(clistp->c_cf, dest, numc); + amount -= numc; + clistp->c_cf += numc; + clistp->c_cc -= numc; + dest += numc; + if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) { + if (clistp->c_cc > 0) { + clistp->c_cf = cblockp->c_next->c_info; + } else { + clistp->c_cf = clistp->c_cl = NULL; + } + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + } + } + + splx(s); + return (dest - dest_orig); } +/* + * Flush 'amount' of chars, beginning at head of clist 'clistp'. + */ void -ndflush(a1, a2) - struct clist *a1; - int a2; +ndflush(clistp, amount) + struct clist *clistp; + int amount; { + struct cblock *cblockp; + struct cblock *cblockn; + int numc; + int s; - /* - * Body deleted. - */ + s = spltty(); + + while (amount && (clistp->c_cc > 0)) { + cblockp = (struct cblock *)((long)clistp->c_cf & ~CROUND); + cblockn = cblockp + 1; /* pointer arithmetic! */ + numc = min(amount, (char *)cblockn - clistp->c_cf); + numc = min(numc, clistp->c_cc); + amount -= numc; + clistp->c_cf += numc; + clistp->c_cc -= numc; + if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) { + if (clistp->c_cc > 0) { + clistp->c_cf = cblockp->c_next->c_info; + } else { + clistp->c_cf = clistp->c_cl = NULL; + } + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + } + } + + splx(s); return; } -putc(a1, a2) - char a1; - struct clist *a2; +int +putc(chr, clistp) + int chr; + struct clist *clistp; { + struct cblock *cblockp; + struct cblock *bclockn; + int s; - /* - * Body deleted. - */ + s = spltty(); + + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); + + if (clistp->c_cl == NULL) { + if (cfreelist) { + cblockp = cfreelist; + cfreelist = cfreelist->c_next; + cfreecount -= CBSIZE; + cblockp->c_next = NULL; + clistp->c_cf = clistp->c_cl = cblockp->c_info; + clistp->c_cc = 0; + } else { + splx(s); + return (-1); + } + } else { + if (((long)clistp->c_cl & CROUND) == 0) { + if (cfreelist) { + cblockp = (cblockp-1)->c_next = cfreelist; + cfreelist = cfreelist->c_next; + cfreecount -= CBSIZE; + cblockp->c_next = NULL; + clistp->c_cl = cblockp->c_info; + } else { + splx(s); + return (-1); + } + } + } + +#if 0 + if (chr & TTY_QUOTE) + setbit(cblockp->c_quote, clistp->c_cl - (char *)cblockp->c_info); +#endif + *clistp->c_cl++ = chr; + clistp->c_cc++; + + splx(s); return (0); } -b_to_q(a1, a2, a3) - char *a1; - int a2; - struct clist *a3; +/* + * Copy data from linear buffer to clist chain. + */ +int +b_to_q(src, amount, clistp) + char *src; + int amount; + struct clist *clistp; { + struct cblock *cblockp; + struct cblock *bclockn; + int s; + int numc; + + s = spltty(); /* - * Body deleted. + * If there are no cblocks assigned to this clist yet, + * then get one. */ - return (0); + if (clistp->c_cl == NULL) { + if (cfreelist) { + cblockp = cfreelist; + cfreelist = cfreelist->c_next; + cfreecount -= CBSIZE; + cblockp->c_next = NULL; + clistp->c_cf = clistp->c_cl = cblockp->c_info; + clistp->c_cc = 0; + } else { + splx(s); + return (amount); + } + } else { + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); + } + + while (amount) { + /* + * Get another cblock if needed. + */ + if (((long)clistp->c_cl & CROUND) == 0) { + if (cfreelist) { + cblockp = (cblockp-1)->c_next = cfreelist; + cfreelist = cfreelist->c_next; + cfreecount -= CBSIZE; + cblockp->c_next = NULL; + clistp->c_cl = cblockp->c_info; + } else { + splx(s); + return (amount); + } + } + + /* + * Copy a chunk of the linear buffer up to the end + * of this cblock. + */ + cblockp += 1; + numc = min(amount, (char *)(cblockp) - clistp->c_cl); + bcopy(src, clistp->c_cl, numc); + + /* + * Clear quote bits. + */ + + /* + * ...and update pointer for the next chunk. + */ + src += numc; + clistp->c_cl += numc; + clistp->c_cc += numc; + amount -= numc; + } + + splx(s); + return (amount); } char * -nextc(a1, a2, a3) - struct clist *a1; - char *a2; - int *a3; +nextc(clistp, cp, dst) + struct clist *clistp; + char *cp; + int *dst; { + struct cblock *cblockp; - /* - * Body deleted. - */ - return ((char *)0); + ++cp; + if (clistp->c_cc && (cp != clistp->c_cl)) { + if (((long)cp & CROUND) == 0) + cp = ((struct cblock *)cp - 1)->c_next->c_info; + cblockp = (struct cblock *)((long)cp & ~CROUND); +#if 0 + *dst = *cp | (isset(cblockp->c_quote, cp - (char *)cblockp->c_info) ? TTY_QUOTE : 0); +#endif + *dst = (u_char)*cp; + return (cp); + } + + return (NULL); } -unputc(a1) - struct clist *a1; +int +unputc(clistp) + struct clist *clistp; { + struct cblock *cblockp = 0, *cbp = 0; + int s; + int chr = -1; + + + s = spltty(); + + if (clistp->c_cc) { + --clistp->c_cc; + chr = (u_char)*--clistp->c_cl; + /* + * Get the quote flag and 'unput' it, too. + */ + + /* XXX write me! */ + + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); + + /* + * If all of the characters have been unput in this + * cblock, the find the previous one and free this + * one. + */ + if (clistp->c_cc && (clistp->c_cl <= (char *)cblockp->c_info)) { + cbp = (struct cblock *)((long)clistp->c_cf & ~CROUND); + + while (cbp->c_next != cblockp) + cbp = cbp->c_next; + + clistp->c_cl = (char *)(cbp+1); + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + cbp->c_next = NULL; + } + } /* - * Body deleted. + * If there are no more characters on the list, then + * free the last cblock. */ - return ((char)0); + if ((clistp->c_cc == 0) && clistp->c_cl) { + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); + cblockp->c_next = cfreelist; + cfreelist = cblockp; + cfreecount += CBSIZE; + clistp->c_cf = clistp->c_cl = NULL; + } + + splx(s); + return (chr); } void -catq(a1, a2) - struct clist *a1, *a2; +catq(src_clistp, dest_clistp) + struct clist *src_clistp, *dest_clistp; { + char buffer[CBSIZE*2]; + int amount; + + while (src_clistp->c_cc) { + amount = q_to_b(src_clistp, buffer, sizeof(buffer)); + b_to_q(buffer, amount, dest_clistp); + } - /* - * Body deleted. - */ return; } diff --git a/sys/kern/tty_tty.c b/sys/kern/tty_tty.c index 964fc6f6d5ed..6baba9932400 100644 --- a/sys/kern/tty_tty.c +++ b/sys/kern/tty_tty.c @@ -48,6 +48,7 @@ #define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL) /*ARGSUSED*/ +int cttyopen(dev, flag, mode, p) dev_t dev; int flag, mode; @@ -78,6 +79,7 @@ cttyopen(dev, flag, mode, p) } /*ARGSUSED*/ +int cttyread(dev, uio, flag) dev_t dev; struct uio *uio; @@ -95,6 +97,7 @@ cttyread(dev, uio, flag) } /*ARGSUSED*/ +int cttywrite(dev, uio, flag) dev_t dev; struct uio *uio; @@ -112,6 +115,7 @@ cttywrite(dev, uio, flag) } /*ARGSUSED*/ +int cttyioctl(dev, cmd, addr, flag, p) dev_t dev; int cmd; @@ -134,6 +138,7 @@ cttyioctl(dev, cmd, addr, flag, p) } /*ARGSUSED*/ +int cttyselect(dev, flag, p) dev_t dev; int flag; diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 8834dbf44427..db082c73660e 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -54,6 +54,7 @@ void pfslowtimo __P((void *)); domains = &__CONCAT(x,domain); \ } +void domaininit() { register struct domain *dp; @@ -141,6 +142,7 @@ found: return (maybe); } +int net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) int *name; u_int namelen; @@ -178,6 +180,7 @@ found: return (ENOPROTOOPT); } +void pfctlinput(cmd, sa) int cmd; struct sockaddr *sa; diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index b71c6345e361..5569bea97dbf 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -47,10 +47,13 @@ #include <vm/vm.h> +void m_reclaim __P(()); + extern vm_map_t mb_map; struct mbuf *mbutl; char *mclrefcnt; +void mbinit() { int s; @@ -75,6 +78,7 @@ bad: * Must be called at splimp. */ /* ARGSUSED */ +int m_clalloc(ncl, nowait) register int ncl; int nowait; @@ -137,6 +141,7 @@ m_retryhdr(i, t) return (m); } +void m_reclaim() { register struct domain *dp; @@ -323,6 +328,7 @@ nospace: * Copy data from an mbuf chain starting "off" bytes from the beginning, * continuing for "len" bytes, into the indicated buffer. */ +void m_copydata(m, off, len, cp) register struct mbuf *m; register int off; @@ -358,6 +364,7 @@ m_copydata(m, off, len, cp) * Both chains must be of the same type (e.g. MT_DATA). * Any m_pkthdr is not updated. */ +void m_cat(m, n) register struct mbuf *m, *n; { @@ -378,6 +385,7 @@ m_cat(m, n) } } +void m_adj(mp, req_len) struct mbuf *mp; int req_len; diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index d4af592d79b5..dc153bd0cae3 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -44,6 +44,14 @@ #include <sys/socket.h> #include <sys/socketvar.h> +void soqinsque __P((struct socket *, struct socket *, int)); +void sowakeup __P((struct socket *, struct sockbuf *)); +void sbrelease __P((struct sockbuf *)); +void sbappendrecord __P((struct sockbuf *, struct mbuf *)); +void sbcompress __P((struct sockbuf *, struct mbuf *, struct mbuf *)); +void sbflush __P((struct sockbuf *)); +void sbdrop __P((struct sockbuf *, int)); + /* * Primitive routines for operating on sockets and socket buffers */ @@ -85,6 +93,7 @@ u_long sb_max = SB_MAX; /* patchable */ * cause software-interrupt process scheduling. */ +void soisconnecting(so) register struct socket *so; { @@ -93,6 +102,7 @@ soisconnecting(so) so->so_state |= SS_ISCONNECTING; } +void soisconnected(so) register struct socket *so; { @@ -111,6 +121,7 @@ soisconnected(so) } } +void soisdisconnecting(so) register struct socket *so; { @@ -122,6 +133,7 @@ soisdisconnecting(so) sorwakeup(so); } +void soisdisconnected(so) register struct socket *so; { @@ -181,6 +193,7 @@ sonewconn1(head, connstatus) return (so); } +void soqinsque(head, so, q) register struct socket *head, *so; int q; @@ -202,6 +215,7 @@ soqinsque(head, so, q) *prev = so; } +int soqremque(so, q) register struct socket *so; int q; @@ -240,6 +254,7 @@ soqremque(so, q) * Data queued for reading in the socket may yet be read. */ +void socantsendmore(so) struct socket *so; { @@ -248,6 +263,7 @@ socantsendmore(so) sowwakeup(so); } +void socantrcvmore(so) struct socket *so; { @@ -259,6 +275,7 @@ socantrcvmore(so) /* * Wait for data to arrive at/drain from a socket buffer. */ +int sbwait(sb) struct sockbuf *sb; { @@ -273,6 +290,7 @@ sbwait(sb) * Lock a sockbuf already known to be locked; * return any error returned from sleep (EINTR). */ +int sb_lock(sb) register struct sockbuf *sb; { @@ -294,6 +312,7 @@ sb_lock(sb) * Do asynchronous notification via SIGIO * if the socket has the SS_ASYNC flag set. */ +void sowakeup(so, sb) register struct socket *so; register struct sockbuf *sb; @@ -346,6 +365,7 @@ sowakeup(so, sb) * should be released by calling sbrelease() when the socket is destroyed. */ +int soreserve(so, sndcc, rcvcc) register struct socket *so; u_long sndcc, rcvcc; @@ -373,6 +393,7 @@ bad: * Attempt to scale mbmax so that mbcnt doesn't become limiting * if buffering efficiency is near the normal case. */ +int sbreserve(sb, cc) struct sockbuf *sb; u_long cc; @@ -390,6 +411,7 @@ sbreserve(sb, cc) /* * Free mbufs held by a socket, and reserved mbuf space. */ +void sbrelease(sb) struct sockbuf *sb; { @@ -429,6 +451,7 @@ sbrelease(sb) * the mbuf chain is recorded in sb. Empty mbufs are * discarded and mbufs are compacted where possible. */ +void sbappend(sb, m) struct sockbuf *sb; struct mbuf *m; @@ -451,6 +474,7 @@ sbappend(sb, m) } #ifdef SOCKBUF_DEBUG +void sbcheck(sb) register struct sockbuf *sb; { @@ -477,6 +501,7 @@ sbcheck(sb) * As above, except the mbuf chain * begins a new record. */ +void sbappendrecord(sb, m0) register struct sockbuf *sb; register struct mbuf *m0; @@ -511,6 +536,7 @@ sbappendrecord(sb, m0) * is inserted at the beginning of the sockbuf, * but after any other OOB data. */ +void sbinsertoob(sb, m0) register struct sockbuf *sb; register struct mbuf *m0; @@ -555,6 +581,7 @@ sbinsertoob(sb, m0) * m0 must include a packet header with total length. * Returns 0 if no space in sockbuf or insufficient mbufs. */ +int sbappendaddr(sb, asa, m0, control) register struct sockbuf *sb; struct sockaddr *asa; @@ -597,6 +624,7 @@ panic("sbappendaddr"); return (1); } +int sbappendcontrol(sb, m0, control) struct sockbuf *sb; struct mbuf *control, *m0; @@ -633,6 +661,7 @@ sbappendcontrol(sb, m0, control) * buffer sb following mbuf n. If n * is null, the buffer is presumed empty. */ +void sbcompress(sb, m, n) register struct sockbuf *sb; register struct mbuf *m, *n; @@ -681,6 +710,7 @@ sbcompress(sb, m, n) * Free all mbufs in a sockbuf. * Check that all resources are reclaimed. */ +void sbflush(sb) register struct sockbuf *sb; { @@ -696,6 +726,7 @@ sbflush(sb) /* * Drop data from (the front of) a sockbuf. */ +void sbdrop(sb, len) register struct sockbuf *sb; register int len; @@ -739,6 +770,7 @@ sbdrop(sb, len) * Drop a record off the front of a sockbuf * and move the next record to the front. */ +void sbdroprecord(sb) register struct sockbuf *sb; { diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index ed09ee63b9f4..ede6c08cf49c 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -46,6 +46,9 @@ #include <sys/socketvar.h> #include <sys/resourcevar.h> +void sofree __P((struct socket *)); +void sorflush __P((struct socket *)); + /* * Socket operation routines. * These routines are called by the routines in @@ -54,6 +57,7 @@ * switching out to the protocol specific routines. */ /*ARGSUSED*/ +int socreate(dom, aso, type, proto) int dom; struct socket **aso; @@ -91,6 +95,7 @@ socreate(dom, aso, type, proto) return (0); } +int sobind(so, nam) struct socket *so; struct mbuf *nam; @@ -105,6 +110,7 @@ sobind(so, nam) return (error); } +int solisten(so, backlog) register struct socket *so; int backlog; @@ -127,6 +133,7 @@ solisten(so, backlog) return (0); } +void sofree(so) register struct socket *so; { @@ -148,6 +155,7 @@ sofree(so) * Initiate disconnect if connected. * Free socket when disconnect complete. */ +int soclose(so) register struct socket *so; { @@ -198,6 +206,7 @@ discard: /* * Must be called at splnet... */ +int soabort(so) struct socket *so; { @@ -207,6 +216,7 @@ soabort(so) (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)); } +int soaccept(so, nam) register struct socket *so; struct mbuf *nam; @@ -223,6 +233,7 @@ soaccept(so, nam) return (error); } +int soconnect(so, nam) register struct socket *so; struct mbuf *nam; @@ -250,6 +261,7 @@ soconnect(so, nam) return (error); } +int soconnect2(so1, so2) register struct socket *so1; struct socket *so2; @@ -263,6 +275,7 @@ soconnect2(so1, so2) return (error); } +int sodisconnect(so) register struct socket *so; { @@ -302,6 +315,7 @@ bad: * must check for short counts if EINTR/ERESTART are returned. * Data and control buffers are freed on return. */ +int sosend(so, addr, uio, top, control, flags) register struct socket *so; struct mbuf *addr; @@ -477,6 +491,7 @@ out: * an mbuf **mp0 for use in returning the chain. The uio is then used * only for the count in uio_resid. */ +int soreceive(so, paddr, uio, mp0, controlp, flagsp) register struct socket *so; struct mbuf **paddr; @@ -489,7 +504,7 @@ soreceive(so, paddr, uio, mp0, controlp, flagsp) register int flags, len, error, s, offset; struct protosw *pr = so->so_proto; struct mbuf *nextrecord; - int moff, type; + int moff, type = 0; int orig_resid = uio->uio_resid; mp = mp0; @@ -775,6 +790,7 @@ release: return (error); } +int soshutdown(so, how) register struct socket *so; register int how; @@ -790,6 +806,7 @@ soshutdown(so, how) return (0); } +void sorflush(so) register struct socket *so; { @@ -811,6 +828,7 @@ sorflush(so) sbrelease(&asb); } +int sosetopt(so, level, optname, m0) register struct socket *so; int level, optname; @@ -927,6 +945,7 @@ bad: return (error); } +int sogetopt(so, level, optname, mp) register struct socket *so; int level, optname; @@ -1011,6 +1030,7 @@ sogetopt(so, level, optname, mp) } } +void sohasoutofband(so) register struct socket *so; { diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index d4af592d79b5..dc153bd0cae3 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -44,6 +44,14 @@ #include <sys/socket.h> #include <sys/socketvar.h> +void soqinsque __P((struct socket *, struct socket *, int)); +void sowakeup __P((struct socket *, struct sockbuf *)); +void sbrelease __P((struct sockbuf *)); +void sbappendrecord __P((struct sockbuf *, struct mbuf *)); +void sbcompress __P((struct sockbuf *, struct mbuf *, struct mbuf *)); +void sbflush __P((struct sockbuf *)); +void sbdrop __P((struct sockbuf *, int)); + /* * Primitive routines for operating on sockets and socket buffers */ @@ -85,6 +93,7 @@ u_long sb_max = SB_MAX; /* patchable */ * cause software-interrupt process scheduling. */ +void soisconnecting(so) register struct socket *so; { @@ -93,6 +102,7 @@ soisconnecting(so) so->so_state |= SS_ISCONNECTING; } +void soisconnected(so) register struct socket *so; { @@ -111,6 +121,7 @@ soisconnected(so) } } +void soisdisconnecting(so) register struct socket *so; { @@ -122,6 +133,7 @@ soisdisconnecting(so) sorwakeup(so); } +void soisdisconnected(so) register struct socket *so; { @@ -181,6 +193,7 @@ sonewconn1(head, connstatus) return (so); } +void soqinsque(head, so, q) register struct socket *head, *so; int q; @@ -202,6 +215,7 @@ soqinsque(head, so, q) *prev = so; } +int soqremque(so, q) register struct socket *so; int q; @@ -240,6 +254,7 @@ soqremque(so, q) * Data queued for reading in the socket may yet be read. */ +void socantsendmore(so) struct socket *so; { @@ -248,6 +263,7 @@ socantsendmore(so) sowwakeup(so); } +void socantrcvmore(so) struct socket *so; { @@ -259,6 +275,7 @@ socantrcvmore(so) /* * Wait for data to arrive at/drain from a socket buffer. */ +int sbwait(sb) struct sockbuf *sb; { @@ -273,6 +290,7 @@ sbwait(sb) * Lock a sockbuf already known to be locked; * return any error returned from sleep (EINTR). */ +int sb_lock(sb) register struct sockbuf *sb; { @@ -294,6 +312,7 @@ sb_lock(sb) * Do asynchronous notification via SIGIO * if the socket has the SS_ASYNC flag set. */ +void sowakeup(so, sb) register struct socket *so; register struct sockbuf *sb; @@ -346,6 +365,7 @@ sowakeup(so, sb) * should be released by calling sbrelease() when the socket is destroyed. */ +int soreserve(so, sndcc, rcvcc) register struct socket *so; u_long sndcc, rcvcc; @@ -373,6 +393,7 @@ bad: * Attempt to scale mbmax so that mbcnt doesn't become limiting * if buffering efficiency is near the normal case. */ +int sbreserve(sb, cc) struct sockbuf *sb; u_long cc; @@ -390,6 +411,7 @@ sbreserve(sb, cc) /* * Free mbufs held by a socket, and reserved mbuf space. */ +void sbrelease(sb) struct sockbuf *sb; { @@ -429,6 +451,7 @@ sbrelease(sb) * the mbuf chain is recorded in sb. Empty mbufs are * discarded and mbufs are compacted where possible. */ +void sbappend(sb, m) struct sockbuf *sb; struct mbuf *m; @@ -451,6 +474,7 @@ sbappend(sb, m) } #ifdef SOCKBUF_DEBUG +void sbcheck(sb) register struct sockbuf *sb; { @@ -477,6 +501,7 @@ sbcheck(sb) * As above, except the mbuf chain * begins a new record. */ +void sbappendrecord(sb, m0) register struct sockbuf *sb; register struct mbuf *m0; @@ -511,6 +536,7 @@ sbappendrecord(sb, m0) * is inserted at the beginning of the sockbuf, * but after any other OOB data. */ +void sbinsertoob(sb, m0) register struct sockbuf *sb; register struct mbuf *m0; @@ -555,6 +581,7 @@ sbinsertoob(sb, m0) * m0 must include a packet header with total length. * Returns 0 if no space in sockbuf or insufficient mbufs. */ +int sbappendaddr(sb, asa, m0, control) register struct sockbuf *sb; struct sockaddr *asa; @@ -597,6 +624,7 @@ panic("sbappendaddr"); return (1); } +int sbappendcontrol(sb, m0, control) struct sockbuf *sb; struct mbuf *control, *m0; @@ -633,6 +661,7 @@ sbappendcontrol(sb, m0, control) * buffer sb following mbuf n. If n * is null, the buffer is presumed empty. */ +void sbcompress(sb, m, n) register struct sockbuf *sb; register struct mbuf *m, *n; @@ -681,6 +710,7 @@ sbcompress(sb, m, n) * Free all mbufs in a sockbuf. * Check that all resources are reclaimed. */ +void sbflush(sb) register struct sockbuf *sb; { @@ -696,6 +726,7 @@ sbflush(sb) /* * Drop data from (the front of) a sockbuf. */ +void sbdrop(sb, len) register struct sockbuf *sb; register int len; @@ -739,6 +770,7 @@ sbdrop(sb, len) * Drop a record off the front of a sockbuf * and move the next record to the front. */ +void sbdroprecord(sb) register struct sockbuf *sb; { diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 89b7ffdf1960..5113f78f4ee7 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -34,6 +34,7 @@ */ #include <sys/param.h> +#include <sys/systm.h> #include <sys/filedesc.h> #include <sys/proc.h> #include <sys/file.h> @@ -61,6 +62,7 @@ struct socket_args { int type; int protocol; }; +int socket(p, uap, retval) struct proc *p; register struct socket_args *uap; @@ -92,6 +94,7 @@ struct bind_args { int namelen; }; /* ARGSUSED */ +int bind(p, uap, retval) struct proc *p; register struct bind_args *uap; @@ -115,6 +118,7 @@ struct listen_args { int backlog; }; /* ARGSUSED */ +int listen(p, uap, retval) struct proc *p; register struct listen_args *uap; @@ -138,6 +142,7 @@ struct accept_args { }; #ifdef COMPAT_OLDSOCK +int accept(p, uap, retval) struct proc *p; struct accept_args *uap; @@ -148,6 +153,7 @@ accept(p, uap, retval) return (accept1(p, uap, retval)); } +int oaccept(p, uap, retval) struct proc *p; struct accept_args *uap; @@ -162,6 +168,7 @@ oaccept(p, uap, retval) #define accept1 accept #endif +int accept1(p, uap, retval) struct proc *p; register struct accept_args *uap; @@ -244,6 +251,7 @@ struct connect_args { int namelen; }; /* ARGSUSED */ +int connect(p, uap, retval) struct proc *p; register struct connect_args *uap; @@ -292,6 +300,7 @@ struct socketpair_args { int protocol; int *rsv; }; +int socketpair(p, uap, retval) struct proc *p; register struct socketpair_args *uap; @@ -354,6 +363,7 @@ struct sendto_args { caddr_t to; int tolen; }; +int sendto(p, uap, retval) struct proc *p; register struct sendto_args *uap; @@ -382,6 +392,7 @@ struct osend_args { int len; int flags; }; +int osend(p, uap, retval) struct proc *p; register struct osend_args *uap; @@ -407,6 +418,7 @@ struct osendmsg_args { caddr_t msg; int flags; }; +int osendmsg(p, uap, retval) struct proc *p; register struct osendmsg_args *uap; @@ -444,6 +456,7 @@ struct sendmsg_args { caddr_t msg; int flags; }; +int sendmsg(p, uap, retval) struct proc *p; register struct sendmsg_args *uap; @@ -478,6 +491,7 @@ done: return (error); } +int sendit(p, s, mp, flags, retsize) register struct proc *p; int s; @@ -505,8 +519,6 @@ sendit(p, s, mp, flags, retsize) auio.uio_resid = 0; iov = mp->msg_iov; for (i = 0; i < mp->msg_iovlen; i++, iov++) { - if (iov->iov_len < 0) - return (EINVAL); if ((auio.uio_resid += iov->iov_len) < 0) return (EINVAL); } @@ -589,6 +601,7 @@ struct recvfrom_args { }; #ifdef COMPAT_OLDSOCK +int orecvfrom(p, uap, retval) struct proc *p; struct recvfrom_args *uap; @@ -600,6 +613,7 @@ orecvfrom(p, uap, retval) } #endif +int recvfrom(p, uap, retval) struct proc *p; register struct recvfrom_args *uap; @@ -632,6 +646,7 @@ struct orecv_args { int len; int flags; }; +int orecv(p, uap, retval) struct proc *p; register struct orecv_args *uap; @@ -661,6 +676,7 @@ struct orecvmsg_args { struct omsghdr *msg; int flags; }; +int orecvmsg(p, uap, retval) struct proc *p; register struct orecvmsg_args *uap; @@ -703,6 +719,7 @@ struct recvmsg_args { struct msghdr *msg; int flags; }; +int recvmsg(p, uap, retval) struct proc *p; register struct recvmsg_args *uap; @@ -742,6 +759,7 @@ done: return (error); } +int recvit(p, s, mp, namelenp, retsize) register struct proc *p; int s; @@ -770,8 +788,6 @@ recvit(p, s, mp, namelenp, retsize) auio.uio_resid = 0; iov = mp->msg_iov; for (i = 0; i < mp->msg_iovlen; i++, iov++) { - if (iov->iov_len < 0) - return (EINVAL); if ((auio.uio_resid += iov->iov_len) < 0) return (EINVAL); } @@ -877,6 +893,7 @@ struct shutdown_args { int how; }; /* ARGSUSED */ +int shutdown(p, uap, retval) struct proc *p; register struct shutdown_args *uap; @@ -898,6 +915,7 @@ struct setsockopt_args { int valsize; }; /* ARGSUSED */ +int setsockopt(p, uap, retval) struct proc *p; register struct setsockopt_args *uap; @@ -934,6 +952,7 @@ struct getsockopt_args { int *avalsize; }; /* ARGSUSED */ +int getsockopt(p, uap, retval) struct proc *p; register struct getsockopt_args *uap; @@ -969,6 +988,7 @@ struct pipe_args { int dummy; }; /* ARGSUSED */ +int pipe(p, uap, retval) struct proc *p; struct pipe_args *uap; @@ -1025,6 +1045,7 @@ struct getsockname_args { #endif }; #ifdef COMPAT_OLDSOCK +int getsockname(p, uap, retval) struct proc *p; struct getsockname_args *uap; @@ -1035,6 +1056,7 @@ getsockname(p, uap, retval) return (getsockname1(p, uap, retval)); } +int ogetsockname(p, uap, retval) struct proc *p; struct getsockname_args *uap; @@ -1050,6 +1072,7 @@ ogetsockname(p, uap, retval) #endif /* ARGSUSED */ +int getsockname1(p, uap, retval) struct proc *p; register struct getsockname_args *uap; @@ -1099,6 +1122,7 @@ struct getpeername_args { }; #ifdef COMPAT_OLDSOCK +int getpeername(p, uap, retval) struct proc *p; struct getpeername_args *uap; @@ -1109,6 +1133,7 @@ getpeername(p, uap, retval) return (getpeername1(p, uap, retval)); } +int ogetpeername(p, uap, retval) struct proc *p; struct getpeername_args *uap; @@ -1124,6 +1149,7 @@ ogetpeername(p, uap, retval) #endif /* ARGSUSED */ +int getpeername1(p, uap, retval) struct proc *p; register struct getpeername_args *uap; @@ -1161,6 +1187,7 @@ bad: return (error); } +int sockargs(mp, buf, buflen, type) struct mbuf **mp; caddr_t buf; @@ -1200,6 +1227,7 @@ sockargs(mp, buf, buflen, type) return (error); } +int getsock(fdp, fdes, fpp) struct filedesc *fdp; int fdes; diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 94bf8f744c86..b61e9f4a2372 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -49,6 +49,15 @@ #include <sys/stat.h> #include <sys/mbuf.h> +void unp_detach __P((struct unpcb *)); +void unp_disconnect __P((struct unpcb *)); +void unp_shutdown __P((struct unpcb *)); +void unp_drop __P((struct unpcb *, int)); +void unp_gc __P((void)); +void unp_scan __P((struct mbuf *, void (*)(struct file *))); +void unp_mark __P((struct file *)); +void unp_discard __P((struct file *)); + /* * Unix communications domain. * @@ -61,6 +70,7 @@ struct sockaddr sun_noname = { sizeof(sun_noname), AF_UNIX }; ino_t unp_ino; /* prototype for fake inode numbers */ /*ARGSUSED*/ +int uipc_usrreq(so, req, m, nam, control) struct socket *so; int req; @@ -313,6 +323,7 @@ u_long unpdg_recvspace = 4*1024; int unp_rights; /* file descriptors in flight */ +int unp_attach(so) struct socket *so; { @@ -346,6 +357,7 @@ unp_attach(so) return (0); } +void unp_detach(unp) register struct unpcb *unp; { @@ -376,6 +388,7 @@ unp_detach(unp) } } +int unp_bind(unp, nam, p) struct unpcb *unp; struct mbuf *nam; @@ -423,6 +436,7 @@ unp_bind(unp, nam, p) return (0); } +int unp_connect(so, nam, p) struct socket *so; struct mbuf *nam; @@ -478,6 +492,7 @@ bad: return (error); } +int unp_connect2(so, so2) register struct socket *so; register struct socket *so2; @@ -509,6 +524,7 @@ unp_connect2(so, so2) return (0); } +void unp_disconnect(unp) struct unpcb *unp; { @@ -546,6 +562,7 @@ unp_disconnect(unp) } #ifdef notdef +void unp_abort(unp) struct unpcb *unp; { @@ -554,6 +571,7 @@ unp_abort(unp) } #endif +void unp_shutdown(unp) struct unpcb *unp; { @@ -564,6 +582,7 @@ unp_shutdown(unp) socantrcvmore(so); } +void unp_drop(unp, errno) struct unpcb *unp; int errno; @@ -581,12 +600,14 @@ unp_drop(unp, errno) } #ifdef notdef +void unp_drain() { } #endif +int unp_externalize(rights) struct mbuf *rights; { @@ -618,6 +639,7 @@ unp_externalize(rights) return (0); } +int unp_internalize(control, p) struct mbuf *control; struct proc *p; @@ -652,9 +674,9 @@ unp_internalize(control, p) } int unp_defer, unp_gcing; -int unp_mark(); extern struct domain unixdomain; +void unp_gc() { register struct file *fp, *nextfp; @@ -765,18 +787,18 @@ unp_gc() unp_gcing = 0; } +void unp_dispose(m) struct mbuf *m; { - int unp_discard(); - if (m) unp_scan(m, unp_discard); } +void unp_scan(m0, op) register struct mbuf *m0; - int (*op)(); + void (*op)(struct file *); { register struct mbuf *m; register struct file **rp; @@ -803,6 +825,7 @@ unp_scan(m0, op) } } +void unp_mark(fp) struct file *fp; { @@ -813,6 +836,7 @@ unp_mark(fp) fp->f_flag |= (FMARK|FDEFER); } +void unp_discard(fp) struct file *fp; { diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index ec5c962f7dfd..6c12d7f7fe9f 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -1,181 +1,260 @@ -/*- - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. +/* + * Copyright (c) 1994 John S. Dyson + * 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. + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)vfs_bio.c 8.6 (Berkeley) 1/11/94 + * 3. Absolutely no warranty of function or purpose is made by the author + * John S. Dyson. + * 4. Modifications may be freely made to this file if the above conditions + * are met. */ #include <sys/param.h> #include <sys/systm.h> +#include <sys/kernel.h> #include <sys/proc.h> -#include <sys/buf.h> #include <sys/vnode.h> +#include <sys/buf.h> #include <sys/mount.h> -#include <sys/trace.h> #include <sys/malloc.h> #include <sys/resourcevar.h> - +#include <vm/vm.h> +#include <vm/vm_pageout.h> + +#include <miscfs/specfs/specdev.h> + +struct buf *buf; /* the buffer pool itself */ +int nbuf; /* number of buffer headers */ +int bufpages; /* number of memory pages in the buffer pool */ +struct buf *swbuf; /* swap I/O headers */ +int nswbuf; +#define BUFHSZ 512 +int bufhash = BUFHSZ - 1; + +struct buf *getnewbuf(int,int); +extern vm_map_t buffer_map, io_map; +void vm_hold_free_pages(vm_offset_t from, vm_offset_t to); +void vm_hold_load_pages(vm_offset_t from, vm_offset_t to); /* * Definitions for the buffer hash lists. */ #define BUFHASH(dvp, lbn) \ (&bufhashtbl[((int)(dvp) / sizeof(*(dvp)) + (int)(lbn)) & bufhash]) -LIST_HEAD(bufhashhdr, buf) *bufhashtbl, invalhash; -u_long bufhash; - -/* - * Insq/Remq for the buffer hash lists. - */ -#define binshash(bp, dp) LIST_INSERT_HEAD(dp, bp, b_hash) -#define bremhash(bp) LIST_REMOVE(bp, b_hash) /* * Definitions for the buffer free lists. */ -#define BQUEUES 4 /* number of free buffer queues */ - -#define BQ_LOCKED 0 /* super-blocks &c */ -#define BQ_LRU 1 /* lru, useful buffers */ -#define BQ_AGE 2 /* rubbish */ -#define BQ_EMPTY 3 /* buffer headers with no memory */ +#define BQUEUES 5 /* number of free buffer queues */ +LIST_HEAD(bufhashhdr, buf) bufhashtbl[BUFHSZ], invalhash; TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES]; -int needbuffer; + +#define BQ_NONE 0 /* on no queue */ +#define BQ_LOCKED 1 /* locked buffers */ +#define BQ_LRU 2 /* useful buffers */ +#define BQ_AGE 3 /* less useful buffers */ +#define BQ_EMPTY 4 /* empty buffer headers*/ + +int needsbuffer; /* - * Insq/Remq for the buffer free lists. + * Internal update daemon, process 3 + * The variable vfs_update_wakeup allows for internal syncs. */ -#define binsheadfree(bp, dp) TAILQ_INSERT_HEAD(dp, bp, b_freelist) -#define binstailfree(bp, dp) TAILQ_INSERT_TAIL(dp, bp, b_freelist) - -void -bremfree(bp) - struct buf *bp; -{ - struct bqueues *dp = NULL; - - /* - * We only calculate the head of the freelist when removing - * the last element of the list as that is the only time that - * it is needed (e.g. to reset the tail pointer). - * - * NB: This makes an assumption about how tailq's are implemented. - */ - if (bp->b_freelist.tqe_next == NULL) { - for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++) - if (dp->tqh_last == &bp->b_freelist.tqe_next) - break; - if (dp == &bufqueues[BQUEUES]) - panic("bremfree: lost tail"); - } - TAILQ_REMOVE(dp, bp, b_freelist); -} +int vfs_update_wakeup; /* - * Initialize buffers and hash links for buffers. + * Initialize buffer headers and related structures. */ -void -bufinit() +void bufinit() { - register struct buf *bp; - struct bqueues *dp; - register int i; - int base, residual; - - for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++) - TAILQ_INIT(dp); - bufhashtbl = hashinit(nbuf, M_CACHE, &bufhash); - base = bufpages / nbuf; - residual = bufpages % nbuf; - for (i = 0; i < nbuf; i++) { + struct buf *bp; + int i; + + TAILQ_INIT(&bswlist); + LIST_INIT(&invalhash); + + /* first, make a null hash table */ + for(i=0;i<BUFHSZ;i++) + LIST_INIT(&bufhashtbl[i]); + + /* next, make a null set of free lists */ + for(i=0;i<BQUEUES;i++) + TAILQ_INIT(&bufqueues[i]); + + /* finally, initialize each buffer header and stick on empty q */ + for(i=0;i<nbuf;i++) { bp = &buf[i]; - bzero((char *)bp, sizeof *bp); + bzero(bp, sizeof *bp); + bp->b_flags = B_INVAL; /* we're just an empty header */ bp->b_dev = NODEV; + bp->b_vp = NULL; bp->b_rcred = NOCRED; bp->b_wcred = NOCRED; + bp->b_qindex = BQ_EMPTY; bp->b_vnbufs.le_next = NOLIST; - bp->b_data = buffers + i * MAXBSIZE; - if (i < residual) - bp->b_bufsize = (base + 1) * CLBYTES; - else - bp->b_bufsize = base * CLBYTES; - bp->b_flags = B_INVAL; - dp = bp->b_bufsize ? &bufqueues[BQ_AGE] : &bufqueues[BQ_EMPTY]; - binsheadfree(bp, dp); - binshash(bp, &invalhash); + bp->b_data = (caddr_t)kmem_alloc_pageable(buffer_map, MAXBSIZE); + TAILQ_INSERT_TAIL(&bufqueues[BQ_EMPTY], bp, b_freelist); + LIST_INSERT_HEAD(&invalhash, bp, b_hash); } } -bread(a1, a2, a3, a4, a5) - struct vnode *a1; - daddr_t a2; - int a3; - struct ucred *a4; - struct buf **a5; +/* + * remove the buffer from the appropriate free list + */ +void +bremfree(struct buf *bp) { + int s = splbio(); + if( bp->b_qindex != BQ_NONE) { + TAILQ_REMOVE(&bufqueues[bp->b_qindex], bp, b_freelist); + bp->b_qindex = BQ_NONE; + } else { + panic("bremfree: removing a buffer when not on a queue"); + } + splx(s); +} - /* - * Body deleted. - */ - return (EIO); +/* + * Get a buffer with the specified data. Look in the cache first. + */ +int +bread(struct vnode *vp, daddr_t blkno, int size, struct ucred *cred, + struct buf **bpp) +{ + struct buf *bp; + + bp = getblk (vp, blkno, size, 0, 0); + *bpp = bp; + + /* if not found in cache, do some I/O */ + if ((bp->b_flags & B_CACHE) == 0) { + if (curproc && curproc->p_stats) /* count block I/O */ + curproc->p_stats->p_ru.ru_inblock++; + bp->b_flags |= B_READ; + bp->b_flags &= ~(B_DONE|B_ERROR|B_INVAL); + if( bp->b_rcred == NOCRED) { + if (cred != NOCRED) + crhold(cred); + bp->b_rcred = cred; + } + VOP_STRATEGY(bp); + return( biowait (bp)); + } + + return (0); } -breadn(a1, a2, a3, a4, a5, a6, a7, a8) - struct vnode *a1; - daddr_t a2; int a3; - daddr_t a4[]; int a5[]; - int a6; - struct ucred *a7; - struct buf **a8; +/* + * Operates like bread, but also starts asynchronous I/O on + * read-ahead blocks. + */ +int +breadn(struct vnode *vp, daddr_t blkno, int size, + daddr_t *rablkno, int *rabsize, + int cnt, struct ucred *cred, struct buf **bpp) { + struct buf *bp, *rabp; + int i; + int rv = 0, readwait = 0; + + *bpp = bp = getblk (vp, blkno, size, 0, 0); + + /* if not found in cache, do some I/O */ + if ((bp->b_flags & B_CACHE) == 0) { + if (curproc && curproc->p_stats) /* count block I/O */ + curproc->p_stats->p_ru.ru_inblock++; + bp->b_flags |= B_READ; + bp->b_flags &= ~(B_DONE|B_ERROR|B_INVAL); + if( bp->b_rcred == NOCRED) { + if (cred != NOCRED) + crhold(cred); + bp->b_rcred = cred; + } + VOP_STRATEGY(bp); + ++readwait; + } + + for(i=0;i<cnt;i++, rablkno++, rabsize++) { + if( incore(vp, *rablkno)) { + continue; + } + rabp = getblk (vp, *rablkno, *rabsize, 0, 0); + + if ((rabp->b_flags & B_CACHE) == 0) { + if (curproc && curproc->p_stats) + curproc->p_stats->p_ru.ru_inblock++; + rabp->b_flags |= B_READ | B_ASYNC; + rabp->b_flags &= ~(B_DONE|B_ERROR|B_INVAL); + if( rabp->b_rcred == NOCRED) { + if (cred != NOCRED) + crhold(cred); + rabp->b_rcred = cred; + } + VOP_STRATEGY(rabp); + } else { + brelse(rabp); + } + } - /* - * Body deleted. - */ - return (EIO); + if( readwait) { + rv = biowait (bp); + } + + return (rv); } -bwrite(a1) - struct buf *a1; +/* + * Write, release buffer on completion. (Done by iodone + * if async.) + */ +int +bwrite(struct buf *bp) { + int oldflags = bp->b_flags; + + if(bp->b_flags & B_INVAL) { + brelse(bp); + return (0); + } - /* - * Body deleted. - */ - return (EIO); + if(!(bp->b_flags & B_BUSY)) + panic("bwrite: buffer is not busy???"); + + bp->b_flags &= ~(B_READ|B_DONE|B_ERROR|B_DELWRI); + bp->b_flags |= B_WRITEINPROG; + + if (oldflags & B_ASYNC) { + if (oldflags & B_DELWRI) { + reassignbuf(bp, bp->b_vp); + } else if( curproc) { + ++curproc->p_stats->p_ru.ru_oublock; + } + } + + bp->b_vp->v_numoutput++; + VOP_STRATEGY(bp); + + if( (oldflags & B_ASYNC) == 0) { + int rtval = biowait(bp); + if (oldflags & B_DELWRI) { + reassignbuf(bp, bp->b_vp); + } else if( curproc) { + ++curproc->p_stats->p_ru.ru_oublock; + } + brelse(bp); + return (rtval); + } + + return(0); } int @@ -185,155 +264,469 @@ vn_bwrite(ap) return (bwrite(ap->a_bp)); } -bdwrite(a1) - struct buf *a1; +/* + * Delayed write. (Buffer is marked dirty). + */ +void +bdwrite(struct buf *bp) { - /* - * Body deleted. - */ + if((bp->b_flags & B_BUSY) == 0) { + panic("bdwrite: buffer is not busy"); + } + + if(bp->b_flags & B_INVAL) { + brelse(bp); + return; + } + + if(bp->b_flags & B_TAPE) { + bawrite(bp); + return; + } + + bp->b_flags &= ~B_READ; + if( (bp->b_flags & B_DELWRI) == 0) { + if( curproc) + ++curproc->p_stats->p_ru.ru_oublock; + bp->b_flags |= B_DONE|B_DELWRI; + reassignbuf(bp, bp->b_vp); + } + brelse(bp); return; } -bawrite(a1) - struct buf *a1; +/* + * Asynchronous write. + * Start output on a buffer, but do not wait for it to complete. + * The buffer is released when the output completes. + */ +void +bawrite(struct buf *bp) { - - /* - * Body deleted. - */ - return; + bp->b_flags |= B_ASYNC; + (void) bwrite(bp); } -brelse(a1) - struct buf *a1; +/* + * Release a buffer. + */ +void +brelse(struct buf *bp) { + int x; - /* - * Body deleted. - */ - return; + /* anyone need a "free" block? */ + x=splbio(); + if (needsbuffer) { + needsbuffer = 0; + wakeup((caddr_t)&needsbuffer); + } + /* anyone need this very block? */ + if (bp->b_flags & B_WANTED) { + bp->b_flags &= ~(B_WANTED|B_AGE); + wakeup((caddr_t)bp); + } + + if (bp->b_flags & B_LOCKED) + bp->b_flags &= ~B_ERROR; + + if ((bp->b_flags & (B_NOCACHE|B_INVAL|B_ERROR)) || + (bp->b_bufsize <= 0)) { + bp->b_flags |= B_INVAL; + bp->b_flags &= ~(B_DELWRI|B_CACHE); + if(bp->b_vp) + brelvp(bp); + } + + if( bp->b_qindex != BQ_NONE) + panic("brelse: free buffer onto another queue???"); + + /* enqueue */ + /* buffers with junk contents */ + if(bp->b_bufsize == 0) { + bp->b_qindex = BQ_EMPTY; + TAILQ_INSERT_HEAD(&bufqueues[BQ_EMPTY], bp, b_freelist); + LIST_REMOVE(bp, b_hash); + LIST_INSERT_HEAD(&invalhash, bp, b_hash); + bp->b_dev = NODEV; + } else if(bp->b_flags & (B_ERROR|B_INVAL|B_NOCACHE)) { + bp->b_qindex = BQ_AGE; + TAILQ_INSERT_HEAD(&bufqueues[BQ_AGE], bp, b_freelist); + LIST_REMOVE(bp, b_hash); + LIST_INSERT_HEAD(&invalhash, bp, b_hash); + bp->b_dev = NODEV; + /* buffers that are locked */ + } else if(bp->b_flags & B_LOCKED) { + bp->b_qindex = BQ_LOCKED; + TAILQ_INSERT_TAIL(&bufqueues[BQ_LOCKED], bp, b_freelist); + /* buffers with stale but valid contents */ + } else if(bp->b_flags & B_AGE) { + bp->b_qindex = BQ_AGE; + TAILQ_INSERT_TAIL(&bufqueues[BQ_AGE], bp, b_freelist); + /* buffers with valid and quite potentially reuseable contents */ + } else { + bp->b_qindex = BQ_LRU; + TAILQ_INSERT_TAIL(&bufqueues[BQ_LRU], bp, b_freelist); + } + + /* unlock */ + bp->b_flags &= ~(B_WANTED|B_BUSY|B_ASYNC|B_NOCACHE|B_AGE); + splx(x); } +int freebufspace; +int allocbufspace; + +/* + * Find a buffer header which is available for use. + */ struct buf * -incore(a1, a2) - struct vnode *a1; - daddr_t a2; +getnewbuf(int slpflag, int slptimeo) { + struct buf *bp; + int x; + x = splbio(); +start: + /* can we constitute a new buffer? */ + if (bp = bufqueues[BQ_EMPTY].tqh_first) { + if( bp->b_qindex != BQ_EMPTY) + panic("getnewbuf: inconsistent EMPTY queue"); + bremfree(bp); + goto fillbuf; + } - /* - * Body deleted. - */ - return (0); +tryfree: + if (bp = bufqueues[BQ_AGE].tqh_first) { + if( bp->b_qindex != BQ_AGE) + panic("getnewbuf: inconsistent AGE queue"); + bremfree(bp); + } else if (bp = bufqueues[BQ_LRU].tqh_first) { + if( bp->b_qindex != BQ_LRU) + panic("getnewbuf: inconsistent LRU queue"); + bremfree(bp); + } else { + /* wait for a free buffer of any kind */ + needsbuffer = 1; + tsleep((caddr_t)&needsbuffer, PRIBIO, "newbuf", 0); + splx(x); + return (0); + } + + + /* if we are a delayed write, convert to an async write */ + if (bp->b_flags & B_DELWRI) { + bp->b_flags |= B_BUSY; + bawrite (bp); + goto start; + } + + if(bp->b_vp) + brelvp(bp); + + /* we are not free, nor do we contain interesting data */ + if (bp->b_rcred != NOCRED) + crfree(bp->b_rcred); + if (bp->b_wcred != NOCRED) + crfree(bp->b_wcred); +fillbuf: + bp->b_flags = B_BUSY; + LIST_REMOVE(bp, b_hash); + LIST_INSERT_HEAD(&invalhash, bp, b_hash); + splx(x); + bp->b_dev = NODEV; + bp->b_vp = NULL; + bp->b_blkno = bp->b_lblkno = 0; + bp->b_iodone = 0; + bp->b_error = 0; + bp->b_resid = 0; + bp->b_bcount = 0; + bp->b_wcred = bp->b_rcred = NOCRED; + bp->b_dirtyoff = bp->b_dirtyend = 0; + bp->b_validoff = bp->b_validend = 0; + return (bp); } +/* + * Check to see if a block is currently memory resident. + */ struct buf * -getblk(a1, a2, a3, a4, a5) - struct vnode *a1; - daddr_t a2; - int a3, a4, a5; +incore(struct vnode *vp, daddr_t blkno) { + struct buf *bp; + struct bufhashhdr *bh; + + int s = splbio(); - /* - * Body deleted. - */ - return ((struct buf *)0); + bh = BUFHASH(vp, blkno); + bp = bh->lh_first; + + /* Search hash chain */ + while (bp) { + if( (bp < buf) || (bp >= buf + nbuf)) { + printf("incore: buf out of range: %lx, hash: %d\n", + bp, bh - bufhashtbl); + panic("incore: buf fault"); + } + /* hit */ + if (bp->b_lblkno == blkno && bp->b_vp == vp + && (bp->b_flags & B_INVAL) == 0) + return (bp); + bp = bp->b_hash.le_next; + } + splx(s); + + return(0); } +/* + * Get a block given a specified block and offset into a file/device. + */ struct buf * -geteblk(a1) - int a1; +getblk(struct vnode *vp, daddr_t blkno, int size, int slpflag, int slptimeo) { - - /* - * Body deleted. - */ - return ((struct buf *)0); + struct buf *bp; + int x; + struct bufhashhdr *bh; + + x = splbio(); +loop: + if (bp = incore(vp, blkno)) { + if (bp->b_flags & B_BUSY) { + bp->b_flags |= B_WANTED; + tsleep ((caddr_t)bp, PRIBIO, "getblk", 0); + goto loop; + } + bp->b_flags |= B_BUSY | B_CACHE; + bremfree(bp); + /* + * check for size inconsistancies + */ + if (bp->b_bcount != size) { + printf("getblk: invalid buffer size: %d\n", bp->b_bcount); + bp->b_flags |= B_INVAL; + bwrite(bp); + goto loop; + } + } else { + + if ((bp = getnewbuf(0, 0)) == 0) + goto loop; + allocbuf(bp, size); + /* + * have to check again, because of a possible + * race condition. + */ + if (incore( vp, blkno)) { + allocbuf(bp, 0); + bp->b_flags |= B_INVAL; + brelse(bp); + goto loop; + } + bp->b_blkno = bp->b_lblkno = blkno; + bgetvp(vp, bp); + LIST_REMOVE(bp, b_hash); + bh = BUFHASH(vp, blkno); + LIST_INSERT_HEAD(bh, bp, b_hash); + } + splx(x); + return (bp); } -allocbuf(a1, a2) - struct buf *a1; - int a2; +/* + * Get an empty, disassociated buffer of given size. + */ +struct buf * +geteblk(int size) { - - /* - * Body deleted. - */ - return (0); + struct buf *bp; + while ((bp = getnewbuf(0, 0)) == 0) + ; + allocbuf(bp, size); + bp->b_flags |= B_INVAL; + return (bp); } -struct buf * -getnewbuf(a1, a2) - int a1, a2; +/* + * Modify the length of a buffer's underlying buffer storage without + * destroying information (unless, of course the buffer is shrinking). + */ +void +allocbuf(struct buf *bp, int size) { - /* - * Body deleted. - */ - return ((struct buf *)0); + int newbsize = round_page(size); + + if( newbsize == bp->b_bufsize) { + bp->b_bcount = size; + return; + } else if( newbsize < bp->b_bufsize) { + vm_hold_free_pages( + (vm_offset_t) bp->b_data + newbsize, + (vm_offset_t) bp->b_data + bp->b_bufsize); + } else if( newbsize > bp->b_bufsize) { + vm_hold_load_pages( + (vm_offset_t) bp->b_data + bp->b_bufsize, + (vm_offset_t) bp->b_data + newbsize); + } + + /* adjust buffer cache's idea of memory allocated to buffer contents */ + freebufspace -= newbsize - bp->b_bufsize; + allocbufspace += newbsize - bp->b_bufsize; + + bp->b_bufsize = newbsize; + bp->b_bcount = size; } -biowait(a1) - struct buf *a1; +/* + * Wait for buffer I/O completion, returning error status. + */ +int +biowait(register struct buf *bp) { - - /* - * Body deleted. - */ - return (EIO); + int x; + + x = splbio(); + while ((bp->b_flags & B_DONE) == 0) + tsleep((caddr_t)bp, PRIBIO, "biowait", 0); + if((bp->b_flags & B_ERROR) || bp->b_error) { + if ((bp->b_flags & B_INVAL) == 0) { + bp->b_flags |= B_INVAL; + bp->b_dev = NODEV; + LIST_REMOVE(bp, b_hash); + LIST_INSERT_HEAD(&invalhash, bp, b_hash); + } + if (!bp->b_error) + bp->b_error = EIO; + else + bp->b_flags |= B_ERROR; + splx(x); + return (bp->b_error); + } else { + splx(x); + return (0); + } } +/* + * Finish I/O on a buffer, calling an optional function. + * This is usually called from interrupt level, so process blocking + * is not *a good idea*. + */ void -biodone(a1) - struct buf *a1; +biodone(register struct buf *bp) { + int s; + s = splbio(); + bp->b_flags |= B_DONE; - /* - * Body deleted. - */ - return; + if ((bp->b_flags & B_READ) == 0) { + vwakeup(bp); + } + + /* call optional completion function if requested */ + if (bp->b_flags & B_CALL) { + bp->b_flags &= ~B_CALL; + (*bp->b_iodone)(bp); + splx(s); + return; + } + +/* + * For asynchronous completions, release the buffer now. The brelse + * checks for B_WANTED and will do the wakeup there if necessary - + * so no need to do a wakeup here in the async case. + */ + + if (bp->b_flags & B_ASYNC) { + brelse(bp); + } else { + bp->b_flags &= ~B_WANTED; + wakeup((caddr_t) bp); + } + splx(s); } int count_lock_queue() { + int count; + struct buf *bp; + + count = 0; + for(bp = bufqueues[BQ_LOCKED].tqh_first; + bp != NULL; + bp = bp->b_freelist.tqe_next) + count++; + return(count); +} - /* - * Body deleted. - */ - return (0); +#ifndef UPDATE_INTERVAL +int vfs_update_interval = 30; +#else +int vfs_update_interval = UPDATE_INTERVAL; +#endif + +void +vfs_update() { + (void) spl0(); + while(1) { + tsleep((caddr_t)&vfs_update_wakeup, PRIBIO, "update", + hz * vfs_update_interval); + vfs_update_wakeup = 0; + sync(curproc, NULL, NULL); + } } -#ifdef DIAGNOSTIC /* - * Print out statistics on the current allocation of the buffer pool. - * Can be enabled to print out on every ``sync'' by setting "syncprt" - * in vfs_syscalls.c using sysctl. + * these routines are not in the correct place (yet) + * also they work *ONLY* for kernel_pmap!!! */ void -vfs_bufstats() -{ - int s, i, j, count; - register struct buf *bp; - register struct bqueues *dp; - int counts[MAXBSIZE/CLBYTES+1]; - static char *bname[BQUEUES] = { "LOCKED", "LRU", "AGE", "EMPTY" }; - - for (dp = bufqueues, i = 0; dp < &bufqueues[BQUEUES]; dp++, i++) { - count = 0; - for (j = 0; j <= MAXBSIZE/CLBYTES; j++) - counts[j] = 0; - s = splbio(); - for (bp = dp->tqh_first; bp; bp = bp->b_freelist.tqe_next) { - counts[bp->b_bufsize/CLBYTES]++; - count++; +vm_hold_load_pages(vm_offset_t froma, vm_offset_t toa) { + vm_offset_t pg; + vm_page_t p; + vm_offset_t from = round_page(froma); + vm_offset_t to = round_page(toa); + + for(pg = from ; pg < to ; pg += PAGE_SIZE) { + vm_offset_t pa; + + tryagain: + p = vm_page_alloc(kernel_object, pg - VM_MIN_KERNEL_ADDRESS); + if( !p) { + VM_WAIT; + goto tryagain; } - splx(s); - printf("%s: total-%d", bname[i], count); - for (j = 0; j <= MAXBSIZE/CLBYTES; j++) - if (counts[j] != 0) - printf(", %d-%d", j * CLBYTES, counts[j]); - printf("\n"); + + vm_page_wire(p); + pmap_enter(kernel_pmap, pg, VM_PAGE_TO_PHYS(p), + VM_PROT_READ|VM_PROT_WRITE, 1); } } -#endif /* DIAGNOSTIC */ + +void +vm_hold_free_pages(vm_offset_t froma, vm_offset_t toa) { + vm_offset_t pg; + vm_page_t p; + vm_offset_t from = round_page(froma); + vm_offset_t to = round_page(toa); + + for(pg = from ; pg < to ; pg += PAGE_SIZE) { + vm_offset_t pa; + pa = pmap_kextract(pg); + if( !pa) { + printf("No pa for va: %x\n", pg); + } else { + p = PHYS_TO_VM_PAGE( pa); + pmap_remove(kernel_pmap, pg, pg + PAGE_SIZE); + vm_page_free(p); + } + } +} + +void +bufstats() +{ +} + diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 4ccfd7289a04..2ddf644c98d9 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -186,6 +186,7 @@ cache_lookup(dvp, vpp, cnp) /* * Add an entry to the cache */ +void cache_enter(dvp, vp, cnp) struct vnode *dvp; struct vnode *vp; @@ -252,6 +253,7 @@ cache_enter(dvp, vp, cnp) /* * Name cache initialization, from vfs_init() when we are booting */ +void nchinit() { @@ -263,6 +265,7 @@ nchinit() * Cache flush, a particular vnode; called when a vnode is renamed to * hide entries that would now be invalid */ +void cache_purge(vp) struct vnode *vp; { @@ -288,6 +291,7 @@ cache_purge(vp) * if the cache lru chain is modified while we are dumping the * inode. This makes the algorithm O(n^2), but do you think I care? */ +void cache_purgevfs(mp) struct mount *mp; { diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index c34fbc34a679..40fa3be52f93 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -34,6 +34,7 @@ */ #include <sys/param.h> +#include <sys/systm.h> #include <sys/proc.h> #include <sys/buf.h> #include <sys/vnode.h> @@ -41,7 +42,6 @@ #include <sys/trace.h> #include <sys/malloc.h> #include <sys/resourcevar.h> -#include <libkern/libkern.h> #ifdef DEBUG #include <vm/vm.h> @@ -106,6 +106,7 @@ int doclusterraz = 0; * rbp is the read-ahead block. * If either is NULL, then you don't have to do the I/O. */ +int cluster_read(vp, filesize, lblkno, size, cred, bpp) struct vnode *vp; u_quad_t filesize; diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 9891fe61c198..9535b8a7231e 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -62,6 +62,8 @@ #include <miscfs/specfs/specdev.h> +void insmntque __P((struct vnode *, struct mount *)); + enum vtype iftovt_tab[16] = { VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD, @@ -86,6 +88,7 @@ struct mntlist mountlist; /* mounted filesystem list */ /* * Initialize the vnode management data structures. */ +void vntblinit() { @@ -97,6 +100,7 @@ vntblinit() * Lock a filesystem. * Used to prevent access to it while mounting and unmounting. */ +int vfs_lock(mp) register struct mount *mp; { @@ -131,6 +135,7 @@ vfs_unlock(mp) * Mark a mount point as busy. * Used to synchronize access and to delay unmounting. */ +int vfs_busy(mp) register struct mount *mp; { @@ -149,6 +154,7 @@ vfs_busy(mp) * Free a busy filesystem. * Panic if filesystem is not busy. */ +void vfs_unbusy(mp) register struct mount *mp; { @@ -209,12 +215,14 @@ static u_short xxxfs_mntid; /* * Set vnode attributes to VNOVAL */ -void vattr_null(vap) +void +vattr_null(vap) register struct vattr *vap; { vap->va_type = VNON; - vap->va_size = vap->va_bytes = VNOVAL; + vap->va_size = VNOVAL; + vap->va_bytes = VNOVAL; vap->va_mode = vap->va_nlink = vap->va_uid = vap->va_gid = vap->va_fsid = vap->va_fileid = vap->va_blocksize = vap->va_rdev = @@ -236,6 +244,7 @@ extern struct vattr va_null; /* * Return the next vnode from the free list. */ +int getnewvnode(tag, mp, vops, vpp) enum vtagtype tag; struct mount *mp; @@ -298,6 +307,7 @@ getnewvnode(tag, mp, vops, vpp) /* * Move a vnode from one mount queue to another. */ +void insmntque(vp, mp) register struct vnode *vp; register struct mount *mp; @@ -319,6 +329,7 @@ insmntque(vp, mp) /* * Update outstanding I/O count and do wakeup if requested. */ +void vwakeup(bp) register struct buf *bp; { @@ -411,6 +422,7 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo) /* * Associate a buffer with a vnode. */ +void bgetvp(vp, bp) register struct vnode *vp; register struct buf *bp; @@ -433,6 +445,7 @@ bgetvp(vp, bp) /* * Disassociate a buffer from a vnode. */ +void brelvp(bp) register struct buf *bp; { @@ -455,6 +468,7 @@ brelvp(bp) * Used to assign file specific control information * (indirect blocks) to the vnode to which they belong. */ +void reassignbuf(bp, newvp) register struct buf *bp; register struct vnode *newvp; @@ -486,6 +500,7 @@ reassignbuf(bp, newvp) * Used for root filesystem, argdev, and swap areas. * Also used for memory file system special devices. */ +int bdevvp(dev, vpp) dev_t dev; struct vnode **vpp; @@ -579,6 +594,7 @@ loop: * indicate that the vnode is no longer usable (possibly having * been changed to a new file system type). */ +int vget(vp, lockflag) register struct vnode *vp; int lockflag; @@ -612,7 +628,8 @@ vget(vp, lockflag) /* * Vnode reference, just increment the count */ -void vref(vp) +void +vref(vp) struct vnode *vp; { @@ -624,7 +641,8 @@ void vref(vp) /* * vput(), just unlock and vrele() */ -void vput(vp) +void +vput(vp) register struct vnode *vp; { @@ -636,7 +654,8 @@ void vput(vp) * Vnode release. * If count drops to zero, call inactive routine and return to freelist. */ -void vrele(vp) +void +vrele(vp) register struct vnode *vp; { @@ -663,7 +682,8 @@ void vrele(vp) /* * Page or buffer structure gets a reference. */ -void vhold(vp) +void +vhold(vp) register struct vnode *vp; { @@ -673,7 +693,8 @@ void vhold(vp) /* * Page or buffer structure frees a reference. */ -void holdrele(vp) +void +holdrele(vp) register struct vnode *vp; { @@ -695,6 +716,7 @@ int busyprt = 0; /* print out busy vnodes */ struct ctldebug debug1 = { "busyprt", &busyprt }; #endif +int vflush(mp, skipvp, flags) struct mount *mp; struct vnode *skipvp; @@ -837,7 +859,8 @@ vclean(vp, flags) * Eliminate all activity associated with the requested vnode * and with all vnodes aliased to the requested vnode. */ -void vgoneall(vp) +void +vgoneall(vp) register struct vnode *vp; { register struct vnode *vq; @@ -880,7 +903,8 @@ void vgoneall(vp) * Eliminate all activity associated with a vnode * in preparation for reuse. */ -void vgone(vp) +void +vgone(vp) register struct vnode *vp; { register struct vnode *vq; @@ -966,6 +990,7 @@ void vgone(vp) /* * Lookup a vnode by device number. */ +int vfinddev(dev, type, vpp) dev_t dev; enum vtype type; @@ -985,6 +1010,7 @@ vfinddev(dev, type, vpp) /* * Calculate the total number of references to a special device. */ +int vcount(vp) register struct vnode *vp; { @@ -1016,6 +1042,7 @@ loop: static char *typename[] = { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" }; +void vprint(label, vp) char *label; register struct vnode *vp; @@ -1057,6 +1084,7 @@ vprint(label, vp) * List all of the locked vnodes in the system. * Called when debugging the kernel. */ +void printlockedvnodes() { register struct mount *mp; @@ -1081,6 +1109,7 @@ int kinfo_vgetfailed; * Copyout address of vnode followed by vnode. */ /* ARGSUSED */ +int sysctl_vnode(where, sizep) char *where; size_t *sizep; diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 345c7a79bf20..f5c3d7835314 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -55,7 +55,8 @@ #include <vm/vm.h> #include <sys/sysctl.h> -static int change_dir __P((struct nameidata *ndp, struct proc *p)); +void cvtstat __P((struct stat *, struct ostat *)); +static int change_dir __P((struct nameidata *ndp, struct proc *p)); /* * Virtual File System System Calls @@ -71,6 +72,7 @@ struct mount_args { caddr_t data; }; /* ARGSUSED */ +int mount(p, uap, retval) struct proc *p; register struct mount_args *uap; @@ -78,7 +80,7 @@ mount(p, uap, retval) { register struct vnode *vp; register struct mount *mp; - int error, flag; + int error, flag = 0; struct nameidata nd; /* @@ -200,6 +202,7 @@ struct unmount_args { int flags; }; /* ARGSUSED */ +int unmount(p, uap, retval) struct proc *p; register struct unmount_args *uap; @@ -240,6 +243,7 @@ unmount(p, uap, retval) /* * Do the actual file system unmount. */ +int dounmount(mp, flags, p) register struct mount *mp; int flags; @@ -289,6 +293,7 @@ struct sync_args { int dummy; }; /* ARGSUSED */ +int sync(p, uap, retval) struct proc *p; struct sync_args *uap; @@ -330,6 +335,7 @@ struct quotactl_args { caddr_t arg; }; /* ARGSUSED */ +int quotactl(p, uap, retval) struct proc *p; register struct quotactl_args *uap; @@ -355,6 +361,7 @@ struct statfs_args { struct statfs *buf; }; /* ARGSUSED */ +int statfs(p, uap, retval) struct proc *p; register struct statfs_args *uap; @@ -385,6 +392,7 @@ struct fstatfs_args { struct statfs *buf; }; /* ARGSUSED */ +int fstatfs(p, uap, retval) struct proc *p; register struct fstatfs_args *uap; @@ -413,6 +421,7 @@ struct getfsstat_args { long bufsize; int flags; }; +int getfsstat(p, uap, retval) struct proc *p; register struct getfsstat_args *uap; @@ -459,6 +468,7 @@ struct fchdir_args { int fd; }; /* ARGSUSED */ +int fchdir(p, uap, retval) struct proc *p; struct fchdir_args *uap; @@ -493,6 +503,7 @@ struct chdir_args { char *path; }; /* ARGSUSED */ +int chdir(p, uap, retval) struct proc *p; struct chdir_args *uap; @@ -517,6 +528,7 @@ struct chroot_args { char *path; }; /* ARGSUSED */ +int chroot(p, uap, retval) struct proc *p; struct chroot_args *uap; @@ -570,6 +582,7 @@ struct open_args { int flags; int mode; }; +int open(p, uap, retval) struct proc *p; register struct open_args *uap; @@ -646,6 +659,7 @@ struct ocreat_args { char *path; int mode; }; +int ocreat(p, uap, retval) struct proc *p; register struct ocreat_args *uap; @@ -669,6 +683,7 @@ struct mknod_args { int dev; }; /* ARGSUSED */ +int mknod(p, uap, retval) struct proc *p; register struct mknod_args *uap; @@ -730,6 +745,7 @@ struct mkfifo_args { int mode; }; /* ARGSUSED */ +int mkfifo(p, uap, retval) struct proc *p; register struct mkfifo_args *uap; @@ -770,6 +786,7 @@ struct link_args { char *link; }; /* ARGSUSED */ +int link(p, uap, retval) struct proc *p; register struct link_args *uap; @@ -820,6 +837,7 @@ struct symlink_args { char *link; }; /* ARGSUSED */ +int symlink(p, uap, retval) struct proc *p; register struct symlink_args *uap; @@ -862,6 +880,7 @@ struct unlink_args { char *path; }; /* ARGSUSED */ +int unlink(p, uap, retval) struct proc *p; struct unlink_args *uap; @@ -912,6 +931,7 @@ struct lseek_args { off_t offset; int whence; }; +int lseek(p, uap, retval) struct proc *p; register struct lseek_args *uap; @@ -957,6 +977,7 @@ struct olseek_args { long offset; int whence; }; +int olseek(p, uap, retval) struct proc *p; register struct olseek_args *uap; @@ -982,6 +1003,7 @@ struct access_args { char *path; int flags; }; +int access(p, uap, retval) struct proc *p; register struct access_args *uap; @@ -1029,6 +1051,7 @@ struct ostat_args { struct ostat *ub; }; /* ARGSUSED */ +int ostat(p, uap, retval) struct proc *p; register struct ostat_args *uap; @@ -1059,6 +1082,7 @@ struct olstat_args { struct ostat *ub; }; /* ARGSUSED */ +int olstat(p, uap, retval) struct proc *p; register struct olstat_args *uap; @@ -1084,6 +1108,7 @@ olstat(p, uap, retval) /* * Convert from an old to a new stat structure. */ +void cvtstat(st, ost) struct stat *st; struct ostat *ost; @@ -1118,6 +1143,7 @@ struct stat_args { struct stat *ub; }; /* ARGSUSED */ +int stat(p, uap, retval) struct proc *p; register struct stat_args *uap; @@ -1146,6 +1172,7 @@ struct lstat_args { struct stat *ub; }; /* ARGSUSED */ +int lstat(p, uap, retval) struct proc *p; register struct lstat_args *uap; @@ -1204,6 +1231,7 @@ struct pathconf_args { int name; }; /* ARGSUSED */ +int pathconf(p, uap, retval) struct proc *p; register struct pathconf_args *uap; @@ -1229,6 +1257,7 @@ struct readlink_args { int count; }; /* ARGSUSED */ +int readlink(p, uap, retval) struct proc *p; register struct readlink_args *uap; @@ -1271,6 +1300,7 @@ struct chflags_args { int flags; }; /* ARGSUSED */ +int chflags(p, uap, retval) struct proc *p; register struct chflags_args *uap; @@ -1306,6 +1336,7 @@ struct fchflags_args { int flags; }; /* ARGSUSED */ +int fchflags(p, uap, retval) struct proc *p; register struct fchflags_args *uap; @@ -1340,6 +1371,7 @@ struct chmod_args { int mode; }; /* ARGSUSED */ +int chmod(p, uap, retval) struct proc *p; register struct chmod_args *uap; @@ -1375,6 +1407,7 @@ struct fchmod_args { int mode; }; /* ARGSUSED */ +int fchmod(p, uap, retval) struct proc *p; register struct fchmod_args *uap; @@ -1410,6 +1443,7 @@ struct chown_args { int gid; }; /* ARGSUSED */ +int chown(p, uap, retval) struct proc *p; register struct chown_args *uap; @@ -1447,6 +1481,7 @@ struct fchown_args { int gid; }; /* ARGSUSED */ +int fchown(p, uap, retval) struct proc *p; register struct fchown_args *uap; @@ -1482,6 +1517,7 @@ struct utimes_args { struct timeval *tptr; }; /* ARGSUSED */ +int utimes(p, uap, retval) struct proc *p; register struct utimes_args *uap; @@ -1528,6 +1564,7 @@ struct truncate_args { off_t length; }; /* ARGSUSED */ +int truncate(p, uap, retval) struct proc *p; register struct truncate_args *uap; @@ -1565,6 +1602,7 @@ struct ftruncate_args { off_t length; }; /* ARGSUSED */ +int ftruncate(p, uap, retval) struct proc *p; register struct ftruncate_args *uap; @@ -1602,6 +1640,7 @@ struct otruncate_args { long length; }; /* ARGSUSED */ +int otruncate(p, uap, retval) struct proc *p; register struct otruncate_args *uap; @@ -1622,6 +1661,7 @@ struct oftruncate_args { long length; }; /* ARGSUSED */ +int oftruncate(p, uap, retval) struct proc *p; register struct oftruncate_args *uap; @@ -1642,6 +1682,7 @@ struct fsync_args { int fd; }; /* ARGSUSED */ +int fsync(p, uap, retval) struct proc *p; struct fsync_args *uap; @@ -1669,6 +1710,7 @@ struct rename_args { char *to; }; /* ARGSUSED */ +int rename(p, uap, retval) struct proc *p; register struct rename_args *uap; @@ -1754,6 +1796,7 @@ struct mkdir_args { int mode; }; /* ARGSUSED */ +int mkdir(p, uap, retval) struct proc *p; register struct mkdir_args *uap; @@ -1794,6 +1837,7 @@ struct rmdir_args { char *path; }; /* ARGSUSED */ +int rmdir(p, uap, retval) struct proc *p; struct rmdir_args *uap; @@ -1849,6 +1893,7 @@ struct ogetdirentries_args { u_int count; long *basep; }; +int ogetdirentries(p, uap, retval) struct proc *p; register struct ogetdirentries_args *uap; @@ -1947,6 +1992,7 @@ struct getdirentries_args { u_int count; long *basep; }; +int getdirentries(p, uap, retval) struct proc *p; register struct getdirentries_args *uap; @@ -2057,6 +2103,7 @@ struct revoke_args { char *path; }; /* ARGSUSED */ +int revoke(p, uap, retval) struct proc *p; register struct revoke_args *uap; @@ -2090,6 +2137,7 @@ out: /* * Convert a user file descriptor to a kernel file entry. */ +int getvnode(fdp, fd, fpp) struct filedesc *fdp; struct file **fpp; diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index 1ce7347bdc86..3ab520d652e8 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -217,6 +217,7 @@ struct vattr va_null; /* * Initialize the vnode structures and initialize each file system type. */ +void vfsinit() { struct vfsops **vfsp; diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 9891fe61c198..9535b8a7231e 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -62,6 +62,8 @@ #include <miscfs/specfs/specdev.h> +void insmntque __P((struct vnode *, struct mount *)); + enum vtype iftovt_tab[16] = { VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD, @@ -86,6 +88,7 @@ struct mntlist mountlist; /* mounted filesystem list */ /* * Initialize the vnode management data structures. */ +void vntblinit() { @@ -97,6 +100,7 @@ vntblinit() * Lock a filesystem. * Used to prevent access to it while mounting and unmounting. */ +int vfs_lock(mp) register struct mount *mp; { @@ -131,6 +135,7 @@ vfs_unlock(mp) * Mark a mount point as busy. * Used to synchronize access and to delay unmounting. */ +int vfs_busy(mp) register struct mount *mp; { @@ -149,6 +154,7 @@ vfs_busy(mp) * Free a busy filesystem. * Panic if filesystem is not busy. */ +void vfs_unbusy(mp) register struct mount *mp; { @@ -209,12 +215,14 @@ static u_short xxxfs_mntid; /* * Set vnode attributes to VNOVAL */ -void vattr_null(vap) +void +vattr_null(vap) register struct vattr *vap; { vap->va_type = VNON; - vap->va_size = vap->va_bytes = VNOVAL; + vap->va_size = VNOVAL; + vap->va_bytes = VNOVAL; vap->va_mode = vap->va_nlink = vap->va_uid = vap->va_gid = vap->va_fsid = vap->va_fileid = vap->va_blocksize = vap->va_rdev = @@ -236,6 +244,7 @@ extern struct vattr va_null; /* * Return the next vnode from the free list. */ +int getnewvnode(tag, mp, vops, vpp) enum vtagtype tag; struct mount *mp; @@ -298,6 +307,7 @@ getnewvnode(tag, mp, vops, vpp) /* * Move a vnode from one mount queue to another. */ +void insmntque(vp, mp) register struct vnode *vp; register struct mount *mp; @@ -319,6 +329,7 @@ insmntque(vp, mp) /* * Update outstanding I/O count and do wakeup if requested. */ +void vwakeup(bp) register struct buf *bp; { @@ -411,6 +422,7 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo) /* * Associate a buffer with a vnode. */ +void bgetvp(vp, bp) register struct vnode *vp; register struct buf *bp; @@ -433,6 +445,7 @@ bgetvp(vp, bp) /* * Disassociate a buffer from a vnode. */ +void brelvp(bp) register struct buf *bp; { @@ -455,6 +468,7 @@ brelvp(bp) * Used to assign file specific control information * (indirect blocks) to the vnode to which they belong. */ +void reassignbuf(bp, newvp) register struct buf *bp; register struct vnode *newvp; @@ -486,6 +500,7 @@ reassignbuf(bp, newvp) * Used for root filesystem, argdev, and swap areas. * Also used for memory file system special devices. */ +int bdevvp(dev, vpp) dev_t dev; struct vnode **vpp; @@ -579,6 +594,7 @@ loop: * indicate that the vnode is no longer usable (possibly having * been changed to a new file system type). */ +int vget(vp, lockflag) register struct vnode *vp; int lockflag; @@ -612,7 +628,8 @@ vget(vp, lockflag) /* * Vnode reference, just increment the count */ -void vref(vp) +void +vref(vp) struct vnode *vp; { @@ -624,7 +641,8 @@ void vref(vp) /* * vput(), just unlock and vrele() */ -void vput(vp) +void +vput(vp) register struct vnode *vp; { @@ -636,7 +654,8 @@ void vput(vp) * Vnode release. * If count drops to zero, call inactive routine and return to freelist. */ -void vrele(vp) +void +vrele(vp) register struct vnode *vp; { @@ -663,7 +682,8 @@ void vrele(vp) /* * Page or buffer structure gets a reference. */ -void vhold(vp) +void +vhold(vp) register struct vnode *vp; { @@ -673,7 +693,8 @@ void vhold(vp) /* * Page or buffer structure frees a reference. */ -void holdrele(vp) +void +holdrele(vp) register struct vnode *vp; { @@ -695,6 +716,7 @@ int busyprt = 0; /* print out busy vnodes */ struct ctldebug debug1 = { "busyprt", &busyprt }; #endif +int vflush(mp, skipvp, flags) struct mount *mp; struct vnode *skipvp; @@ -837,7 +859,8 @@ vclean(vp, flags) * Eliminate all activity associated with the requested vnode * and with all vnodes aliased to the requested vnode. */ -void vgoneall(vp) +void +vgoneall(vp) register struct vnode *vp; { register struct vnode *vq; @@ -880,7 +903,8 @@ void vgoneall(vp) * Eliminate all activity associated with a vnode * in preparation for reuse. */ -void vgone(vp) +void +vgone(vp) register struct vnode *vp; { register struct vnode *vq; @@ -966,6 +990,7 @@ void vgone(vp) /* * Lookup a vnode by device number. */ +int vfinddev(dev, type, vpp) dev_t dev; enum vtype type; @@ -985,6 +1010,7 @@ vfinddev(dev, type, vpp) /* * Calculate the total number of references to a special device. */ +int vcount(vp) register struct vnode *vp; { @@ -1016,6 +1042,7 @@ loop: static char *typename[] = { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" }; +void vprint(label, vp) char *label; register struct vnode *vp; @@ -1057,6 +1084,7 @@ vprint(label, vp) * List all of the locked vnodes in the system. * Called when debugging the kernel. */ +void printlockedvnodes() { register struct mount *mp; @@ -1081,6 +1109,7 @@ int kinfo_vgetfailed; * Copyout address of vnode followed by vnode. */ /* ARGSUSED */ +int sysctl_vnode(where, sizep) char *where; size_t *sizep; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 345c7a79bf20..f5c3d7835314 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -55,7 +55,8 @@ #include <vm/vm.h> #include <sys/sysctl.h> -static int change_dir __P((struct nameidata *ndp, struct proc *p)); +void cvtstat __P((struct stat *, struct ostat *)); +static int change_dir __P((struct nameidata *ndp, struct proc *p)); /* * Virtual File System System Calls @@ -71,6 +72,7 @@ struct mount_args { caddr_t data; }; /* ARGSUSED */ +int mount(p, uap, retval) struct proc *p; register struct mount_args *uap; @@ -78,7 +80,7 @@ mount(p, uap, retval) { register struct vnode *vp; register struct mount *mp; - int error, flag; + int error, flag = 0; struct nameidata nd; /* @@ -200,6 +202,7 @@ struct unmount_args { int flags; }; /* ARGSUSED */ +int unmount(p, uap, retval) struct proc *p; register struct unmount_args *uap; @@ -240,6 +243,7 @@ unmount(p, uap, retval) /* * Do the actual file system unmount. */ +int dounmount(mp, flags, p) register struct mount *mp; int flags; @@ -289,6 +293,7 @@ struct sync_args { int dummy; }; /* ARGSUSED */ +int sync(p, uap, retval) struct proc *p; struct sync_args *uap; @@ -330,6 +335,7 @@ struct quotactl_args { caddr_t arg; }; /* ARGSUSED */ +int quotactl(p, uap, retval) struct proc *p; register struct quotactl_args *uap; @@ -355,6 +361,7 @@ struct statfs_args { struct statfs *buf; }; /* ARGSUSED */ +int statfs(p, uap, retval) struct proc *p; register struct statfs_args *uap; @@ -385,6 +392,7 @@ struct fstatfs_args { struct statfs *buf; }; /* ARGSUSED */ +int fstatfs(p, uap, retval) struct proc *p; register struct fstatfs_args *uap; @@ -413,6 +421,7 @@ struct getfsstat_args { long bufsize; int flags; }; +int getfsstat(p, uap, retval) struct proc *p; register struct getfsstat_args *uap; @@ -459,6 +468,7 @@ struct fchdir_args { int fd; }; /* ARGSUSED */ +int fchdir(p, uap, retval) struct proc *p; struct fchdir_args *uap; @@ -493,6 +503,7 @@ struct chdir_args { char *path; }; /* ARGSUSED */ +int chdir(p, uap, retval) struct proc *p; struct chdir_args *uap; @@ -517,6 +528,7 @@ struct chroot_args { char *path; }; /* ARGSUSED */ +int chroot(p, uap, retval) struct proc *p; struct chroot_args *uap; @@ -570,6 +582,7 @@ struct open_args { int flags; int mode; }; +int open(p, uap, retval) struct proc *p; register struct open_args *uap; @@ -646,6 +659,7 @@ struct ocreat_args { char *path; int mode; }; +int ocreat(p, uap, retval) struct proc *p; register struct ocreat_args *uap; @@ -669,6 +683,7 @@ struct mknod_args { int dev; }; /* ARGSUSED */ +int mknod(p, uap, retval) struct proc *p; register struct mknod_args *uap; @@ -730,6 +745,7 @@ struct mkfifo_args { int mode; }; /* ARGSUSED */ +int mkfifo(p, uap, retval) struct proc *p; register struct mkfifo_args *uap; @@ -770,6 +786,7 @@ struct link_args { char *link; }; /* ARGSUSED */ +int link(p, uap, retval) struct proc *p; register struct link_args *uap; @@ -820,6 +837,7 @@ struct symlink_args { char *link; }; /* ARGSUSED */ +int symlink(p, uap, retval) struct proc *p; register struct symlink_args *uap; @@ -862,6 +880,7 @@ struct unlink_args { char *path; }; /* ARGSUSED */ +int unlink(p, uap, retval) struct proc *p; struct unlink_args *uap; @@ -912,6 +931,7 @@ struct lseek_args { off_t offset; int whence; }; +int lseek(p, uap, retval) struct proc *p; register struct lseek_args *uap; @@ -957,6 +977,7 @@ struct olseek_args { long offset; int whence; }; +int olseek(p, uap, retval) struct proc *p; register struct olseek_args *uap; @@ -982,6 +1003,7 @@ struct access_args { char *path; int flags; }; +int access(p, uap, retval) struct proc *p; register struct access_args *uap; @@ -1029,6 +1051,7 @@ struct ostat_args { struct ostat *ub; }; /* ARGSUSED */ +int ostat(p, uap, retval) struct proc *p; register struct ostat_args *uap; @@ -1059,6 +1082,7 @@ struct olstat_args { struct ostat *ub; }; /* ARGSUSED */ +int olstat(p, uap, retval) struct proc *p; register struct olstat_args *uap; @@ -1084,6 +1108,7 @@ olstat(p, uap, retval) /* * Convert from an old to a new stat structure. */ +void cvtstat(st, ost) struct stat *st; struct ostat *ost; @@ -1118,6 +1143,7 @@ struct stat_args { struct stat *ub; }; /* ARGSUSED */ +int stat(p, uap, retval) struct proc *p; register struct stat_args *uap; @@ -1146,6 +1172,7 @@ struct lstat_args { struct stat *ub; }; /* ARGSUSED */ +int lstat(p, uap, retval) struct proc *p; register struct lstat_args *uap; @@ -1204,6 +1231,7 @@ struct pathconf_args { int name; }; /* ARGSUSED */ +int pathconf(p, uap, retval) struct proc *p; register struct pathconf_args *uap; @@ -1229,6 +1257,7 @@ struct readlink_args { int count; }; /* ARGSUSED */ +int readlink(p, uap, retval) struct proc *p; register struct readlink_args *uap; @@ -1271,6 +1300,7 @@ struct chflags_args { int flags; }; /* ARGSUSED */ +int chflags(p, uap, retval) struct proc *p; register struct chflags_args *uap; @@ -1306,6 +1336,7 @@ struct fchflags_args { int flags; }; /* ARGSUSED */ +int fchflags(p, uap, retval) struct proc *p; register struct fchflags_args *uap; @@ -1340,6 +1371,7 @@ struct chmod_args { int mode; }; /* ARGSUSED */ +int chmod(p, uap, retval) struct proc *p; register struct chmod_args *uap; @@ -1375,6 +1407,7 @@ struct fchmod_args { int mode; }; /* ARGSUSED */ +int fchmod(p, uap, retval) struct proc *p; register struct fchmod_args *uap; @@ -1410,6 +1443,7 @@ struct chown_args { int gid; }; /* ARGSUSED */ +int chown(p, uap, retval) struct proc *p; register struct chown_args *uap; @@ -1447,6 +1481,7 @@ struct fchown_args { int gid; }; /* ARGSUSED */ +int fchown(p, uap, retval) struct proc *p; register struct fchown_args *uap; @@ -1482,6 +1517,7 @@ struct utimes_args { struct timeval *tptr; }; /* ARGSUSED */ +int utimes(p, uap, retval) struct proc *p; register struct utimes_args *uap; @@ -1528,6 +1564,7 @@ struct truncate_args { off_t length; }; /* ARGSUSED */ +int truncate(p, uap, retval) struct proc *p; register struct truncate_args *uap; @@ -1565,6 +1602,7 @@ struct ftruncate_args { off_t length; }; /* ARGSUSED */ +int ftruncate(p, uap, retval) struct proc *p; register struct ftruncate_args *uap; @@ -1602,6 +1640,7 @@ struct otruncate_args { long length; }; /* ARGSUSED */ +int otruncate(p, uap, retval) struct proc *p; register struct otruncate_args *uap; @@ -1622,6 +1661,7 @@ struct oftruncate_args { long length; }; /* ARGSUSED */ +int oftruncate(p, uap, retval) struct proc *p; register struct oftruncate_args *uap; @@ -1642,6 +1682,7 @@ struct fsync_args { int fd; }; /* ARGSUSED */ +int fsync(p, uap, retval) struct proc *p; struct fsync_args *uap; @@ -1669,6 +1710,7 @@ struct rename_args { char *to; }; /* ARGSUSED */ +int rename(p, uap, retval) struct proc *p; register struct rename_args *uap; @@ -1754,6 +1796,7 @@ struct mkdir_args { int mode; }; /* ARGSUSED */ +int mkdir(p, uap, retval) struct proc *p; register struct mkdir_args *uap; @@ -1794,6 +1837,7 @@ struct rmdir_args { char *path; }; /* ARGSUSED */ +int rmdir(p, uap, retval) struct proc *p; struct rmdir_args *uap; @@ -1849,6 +1893,7 @@ struct ogetdirentries_args { u_int count; long *basep; }; +int ogetdirentries(p, uap, retval) struct proc *p; register struct ogetdirentries_args *uap; @@ -1947,6 +1992,7 @@ struct getdirentries_args { u_int count; long *basep; }; +int getdirentries(p, uap, retval) struct proc *p; register struct getdirentries_args *uap; @@ -2057,6 +2103,7 @@ struct revoke_args { char *path; }; /* ARGSUSED */ +int revoke(p, uap, retval) struct proc *p; register struct revoke_args *uap; @@ -2090,6 +2137,7 @@ out: /* * Convert a user file descriptor to a kernel file entry. */ +int getvnode(fdp, fd, fpp) struct filedesc *fdp; struct file **fpp; diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index d104bb9de773..d63a39c158bc 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -60,6 +60,7 @@ struct fileops vnops = * Common code for vnode open operations. * Check permissions, and call the VOP_OPEN or VOP_CREATE routine. */ +int vn_open(ndp, fmode, cmode) register struct nameidata *ndp; int fmode, cmode; @@ -152,6 +153,7 @@ bad: * The read-only status of the file system is checked. * Also, prototype text segments cannot be written. */ +int vn_writechk(vp) register struct vnode *vp; { @@ -180,6 +182,7 @@ vn_writechk(vp) /* * Vnode close call */ +int vn_close(vp, flags, cred, p) register struct vnode *vp; int flags; @@ -198,6 +201,7 @@ vn_close(vp, flags, cred, p) /* * Package up an I/O request on a vnode into a uio and do it. */ +int vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p) enum uio_rw rw; struct vnode *vp; @@ -243,6 +247,7 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p) /* * File table vnode read routine. */ +int vn_read(fp, uio, cred) struct file *fp; struct uio *uio; @@ -265,6 +270,7 @@ vn_read(fp, uio, cred) /* * File table vnode write routine. */ +int vn_write(fp, uio, cred) struct file *fp; struct uio *uio; @@ -293,6 +299,7 @@ vn_write(fp, uio, cred) /* * File table vnode stat routine. */ +int vn_stat(vp, sb, p) struct vnode *vp; register struct stat *sb; @@ -357,6 +364,7 @@ vn_stat(vp, sb, p) /* * File table vnode ioctl routine. */ +int vn_ioctl(fp, com, data, p) struct file *fp; int com; @@ -399,6 +407,7 @@ vn_ioctl(fp, com, data, p) /* * File table vnode select routine. */ +int vn_select(fp, which, p) struct file *fp; int which; @@ -412,6 +421,7 @@ vn_select(fp, which, p) /* * File table vnode close routine. */ +int vn_closefile(fp, p) struct file *fp; struct proc *p; |