merge of bill's code plus lint (plus, of course, cleanup of bill's bugs)
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Sat, 28 May 1983 03:51:31 +0000 (19:51 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Sat, 28 May 1983 03:51:31 +0000 (19:51 -0800)
SCCS-vsn: sys/kern/kern_clock.c 4.54
SCCS-vsn: sys/kern/kern_descrip.c 5.24
SCCS-vsn: sys/kern/kern_proc.c 4.64
SCCS-vsn: sys/kern/kern_prot.c 5.17
SCCS-vsn: sys/kern/kern_resource.c 4.22
SCCS-vsn: sys/kern/kern_sig.c 5.17
SCCS-vsn: sys/kern/kern_time.c 5.15
SCCS-vsn: sys/kern/subr_prf.c 4.27
SCCS-vsn: sys/kern/subr_xxx.c 4.22
SCCS-vsn: sys/kern/sys_generic.c 5.36
SCCS-vsn: sys/kern/tty.c 4.41
SCCS-vsn: sys/kern/tty_bk.c 4.9
SCCS-vsn: sys/kern/tty_conf.c 4.3
SCCS-vsn: sys/kern/tty_pty.c 4.31
SCCS-vsn: sys/kern/tty_subr.c 4.20
SCCS-vsn: sys/kern/tty_tb.c 4.8
SCCS-vsn: sys/ufs/ffs/ffs_alloc.c 2.26
SCCS-vsn: sys/ufs/lfs/lfs_alloc.c 2.26
SCCS-vsn: sys/kern/vfs_vnops.c 4.35
SCCS-vsn: sys/kern/vfs_syscalls.c 4.57
SCCS-vsn: sys/ufs/ffs/ffs_vnops.c 4.57
SCCS-vsn: sys/ufs/ffs/ufs_vnops.c 4.57
SCCS-vsn: sys/ufs/lfs/lfs_vnops.c 4.57
SCCS-vsn: sys/ufs/ufs/ufs_vnops.c 4.57
SCCS-vsn: sys/ufs/ffs/ffs_tables.c 2.4
SCCS-vsn: sys/kern/vfs_xxx.c 4.5
SCCS-vsn: sys/kern/uipc_mbuf.c 1.43
SCCS-vsn: sys/kern/uipc_proto.c 4.28
SCCS-vsn: sys/kern/uipc_socket.c 4.75
SCCS-vsn: sys/kern/uipc_socket2.c 4.37
SCCS-vsn: sys/kern/uipc_syscalls.c 4.46
SCCS-vsn: sys/kern/uipc_usrreq.c 1.10

32 files changed:
usr/src/sys/kern/kern_clock.c
usr/src/sys/kern/kern_descrip.c
usr/src/sys/kern/kern_proc.c
usr/src/sys/kern/kern_prot.c
usr/src/sys/kern/kern_resource.c
usr/src/sys/kern/kern_sig.c
usr/src/sys/kern/kern_time.c
usr/src/sys/kern/subr_prf.c
usr/src/sys/kern/subr_xxx.c
usr/src/sys/kern/sys_generic.c
usr/src/sys/kern/tty.c
usr/src/sys/kern/tty_bk.c
usr/src/sys/kern/tty_conf.c
usr/src/sys/kern/tty_pty.c
usr/src/sys/kern/tty_subr.c
usr/src/sys/kern/tty_tb.c
usr/src/sys/kern/uipc_mbuf.c
usr/src/sys/kern/uipc_proto.c
usr/src/sys/kern/uipc_socket.c
usr/src/sys/kern/uipc_socket2.c
usr/src/sys/kern/uipc_syscalls.c
usr/src/sys/kern/uipc_usrreq.c
usr/src/sys/kern/vfs_syscalls.c
usr/src/sys/kern/vfs_vnops.c
usr/src/sys/kern/vfs_xxx.c
usr/src/sys/ufs/ffs/ffs_alloc.c
usr/src/sys/ufs/ffs/ffs_tables.c
usr/src/sys/ufs/ffs/ffs_vnops.c
usr/src/sys/ufs/ffs/ufs_vnops.c
usr/src/sys/ufs/lfs/lfs_alloc.c
usr/src/sys/ufs/lfs/lfs_vnops.c
usr/src/sys/ufs/ufs/ufs_vnops.c

index fffeb95..875b45a 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_clock.c    4.53    83/05/21        */
+/*     kern_clock.c    4.54    83/05/27        */
 
 #include "../machine/reg.h"
 #include "../machine/psl.h"
 
 #include "../machine/reg.h"
 #include "../machine/psl.h"
@@ -43,21 +43,10 @@ extern int phz;
 
 /*
  * TODO:
 
 /*
  * TODO:
- *     * Keep more accurate statistics by simulating good interval timers.
- *     * Use the time-of-day clock on the VAX to keep more accurate time
- *       than is possible by repeated use of the interval timer.
- *     * Allocate more timeout table slots when table overflows.
- *     * Get all resource allocation to use second timer.
+ *     time of day, system/user timing, timeouts, profiling on separate timers
+ *     allocate more timeout table slots when table overflows.
  */
 
  */
 
-/* bump a timeval by a small number of usec's */
-#define        bumptime(tp, usec) \
-       (tp)->tv_usec += usec; \
-       if ((tp)->tv_usec >= 1000000) { \
-               (tp)->tv_usec -= 1000000; \
-               (tp)->tv_sec++; \
-       }
-
 /*
  * The hz hardware interval timer.
  * We update the events relating to real time.
 /*
  * The hz hardware interval timer.
  * We update the events relating to real time.
@@ -75,17 +64,14 @@ hardclock(pc, ps)
 hardclock(regs)
        struct regs regs;
 {
 hardclock(regs)
        struct regs regs;
 {
-       int ps = regs.r_sr;
-       caddr_t pc = (caddr_t)regs.r_pc;
+#define        ps      regs.r_sr
+#define        pc      (caddr_t)regs.r_pc
 #endif
        register struct callout *p1;
        register struct proc *p;
        register int s, cpstate;
 #endif
        register struct callout *p1;
        register struct proc *p;
        register int s, cpstate;
+       int needsoft = 0;
 
 
-#ifdef sun
-       if (USERMODE(ps))               /* aston needs ar0 */
-               u.u_ar0 = &regs.r_r0;
-#endif
        /*
         * Update real-time timeout queue.
         * At front of queue are some number of events which are ``due''.
        /*
         * Update real-time timeout queue.
         * At front of queue are some number of events which are ``due''.
@@ -96,10 +82,15 @@ hardclock(regs)
         * Decrementing just the first of these serves to decrement the time
         * to all events.
         */
         * Decrementing just the first of these serves to decrement the time
         * to all events.
         */
-       for (p1 = calltodo.c_next; p1 && p1->c_time <= 0; p1 = p1->c_next)
-               --p1->c_time;
-       if (p1)
-               --p1->c_time;
+       p1 = calltodo.c_next;
+       while (p1) {
+               if (--p1->c_time > 0)
+                       break;
+               needsoft = 1;
+               if (p1->c_time == 0)
+                       break;
+               p1 = p1->c_next;
+       }
 
        /*
         * Charge the time out based on the mode the cpu is in.
 
        /*
         * Charge the time out based on the mode the cpu is in.
@@ -108,6 +99,11 @@ hardclock(regs)
         * one tick.
         */
        if (USERMODE(ps)) {
         * one tick.
         */
        if (USERMODE(ps)) {
+#ifdef sun
+               u.u_ar0 = &regs.r_r0;   /* aston needs ar0 */
+#endif
+               if (u.u_prof.pr_scale)
+                       needsoft = 1;
                /*
                 * CPU was in user state.  Increment
                 * user time counter, and process process-virtual time
                /*
                 * CPU was in user state.  Increment
                 * user time counter, and process process-virtual time
@@ -221,8 +217,13 @@ hardclock(regs)
         * priority any longer than necessary.
         */
        bumptime(&time, tick);
         * priority any longer than necessary.
         */
        bumptime(&time, tick);
-       setsoftclock();
+       if (needsoft)
+               setsoftclock();
 }
 }
+#ifdef sun
+#undef pc
+#undef ps
+#endif
 
 /*
  * Gather statistics on resource utilization.
 
 /*
  * Gather statistics on resource utilization.
@@ -232,6 +233,7 @@ hardclock(regs)
  * or idle state) for the entire last time interval, and
  * update statistics accordingly.
  */
  * or idle state) for the entire last time interval, and
  * update statistics accordingly.
  */
+/*ARGSUSED*/
 gatherstats(pc, ps)
        caddr_t pc;
        int ps;
 gatherstats(pc, ps)
        caddr_t pc;
        int ps;
@@ -288,8 +290,8 @@ softclock(pc, ps)
 #ifdef sun
 softclock()
 {
 #ifdef sun
 softclock()
 {
-       int ps = u.u_ar0[PS];
-       caddr_t pc = (caddr_t)u.u_ar0[PC];
+#define        pc      (caddr_t)u.u_ar0[PC]
+#define        ps      u.u_ar0[PS]
 #endif
 
        for (;;) {
 #endif
 
        for (;;) {
@@ -320,19 +322,33 @@ softclock()
 }
 
 /*
 }
 
 /*
- * Arrange that (*fun)(arg) is called in tim/hz seconds.
+ * Bump a timeval by a small number of usec's.
+ */
+bumptime(tp, usec)
+       register struct timeval *tp;
+       int usec;
+{
+
+       tp->tv_usec += usec;
+       if (tp->tv_usec >= 1000000) {
+               tp->tv_usec -= 1000000;
+               tp->tv_sec++;
+       }
+}
+
+/*
+ * Arrange that (*fun)(arg) is called in t/hz seconds.
  */
  */
-timeout(fun, arg, tim)
+timeout(fun, arg, t)
        int (*fun)();
        caddr_t arg;
        int (*fun)();
        caddr_t arg;
-       int tim;
+       register int t;
 {
        register struct callout *p1, *p2, *pnew;
 {
        register struct callout *p1, *p2, *pnew;
-       register int t;
-       int s;
+       register int s = spl7();
 
 
-       t = tim;
-       s = spl7();
+       if (t == 0)
+               t = 1;
        pnew = callfree;
        if (pnew == NULL)
                panic("timeout table overflow");
        pnew = callfree;
        if (pnew == NULL)
                panic("timeout table overflow");
@@ -407,3 +423,26 @@ hzto(tv)
        splx(s);
        return (ticks);
 }
        splx(s);
        return (ticks);
 }
+
+profil()
+{
+       register struct a {
+               short   *bufbase;
+               unsigned bufsize;
+               unsigned pcoffset;
+               unsigned pcscale;
+       } *uap = (struct a *)u.u_ap;
+       register struct uprof *upp = &u.u_prof;
+
+       upp->pr_base = uap->bufbase;
+       upp->pr_size = uap->bufsize;
+       upp->pr_off = uap->pcoffset;
+       upp->pr_scale = uap->pcscale;
+}
+
+opause()
+{
+
+       for (;;)
+               sleep((caddr_t)&u, PSLEP);
+}
index 5bd7a0a..81b5652 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_descrip.c  5.23    83/01/17        */
+/*     kern_descrip.c  5.24    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -13,7 +13,7 @@
 #include "../h/socketvar.h"
 #include "../h/mount.h"
 
 #include "../h/socketvar.h"
 #include "../h/mount.h"
 
-#include "../h/descrip.h"
+#include "../h/ioctl.h"
 
 /*
  * Descriptor management.
 
 /*
  * Descriptor management.
@@ -21,8 +21,8 @@
 
 /*
  * TODO:
 
 /*
  * TODO:
- *     getf should be renamed
- *     ufalloc side effects are gross
+ *     increase NOFILE
+ *     eliminate u.u_error side effects
  */
 
 /*
  */
 
 /*
@@ -34,26 +34,6 @@ getdtablesize()
        u.u_r.r_val1 = NOFILE;
 }
 
        u.u_r.r_val1 = NOFILE;
 }
 
-getdprop()
-{
-       register struct a {
-               int     d;
-               struct  dtype *dtypeb;
-       } *uap = (struct a *)u.u_ap;
-       register struct file *fp;
-       struct dtype adtype;
-
-       fp = getf(uap->d);
-       if (fp == 0)
-               return;
-       adtype.dt_type = 0;             /* XXX */
-       adtype.dt_protocol = 0;         /* XXX */
-       u.u_error = copyout((caddr_t)&adtype, (caddr_t)uap->dtypeb,
-           sizeof (struct dtype)); 
-       if (u.u_error)
-               return;
-}
-
 getdopt()
 {
 
 getdopt()
 {
 
@@ -77,10 +57,10 @@ dup()
        fp = getf(uap->i);
        if (fp == 0)
                return;
        fp = getf(uap->i);
        if (fp == 0)
                return;
-       j = ufalloc();
+       j = ufalloc(0);
        if (j < 0)
                return;
        if (j < 0)
                return;
-       dupit(j, fp, u.u_pofile[uap->i] & (UF_SHLOCK|UF_EXLOCK));
+       dupit(j, fp, u.u_pofile[uap->i]);
 }
 
 dup2()
 }
 
 dup2()
@@ -103,13 +83,13 @@ dup2()
        if (u.u_ofile[uap->j]) {
                if (u.u_pofile[uap->j] & UF_MAPPED)
                        munmapfd(uap->j);
        if (u.u_ofile[uap->j]) {
                if (u.u_pofile[uap->j] & UF_MAPPED)
                        munmapfd(uap->j);
-               closef(u.u_ofile[uap->j], 0, u.u_pofile[uap->j]);
+               closef(u.u_ofile[uap->j], u.u_pofile[uap->j]);
                if (u.u_error)
                        return;
                /* u.u_ofile[uap->j] = 0; */
                /* u.u_pofile[uap->j] = 0; */
        }
                if (u.u_error)
                        return;
                /* u.u_ofile[uap->j] = 0; */
                /* u.u_pofile[uap->j] = 0; */
        }
-       dupit(uap->j, fp, u.u_pofile[uap->i] & (UF_SHLOCK|UF_EXLOCK));
+       dupit(uap->j, fp, u.u_pofile[uap->i]);
 }
 
 dupit(fd, fp, lockflags)
 }
 
 dupit(fd, fp, lockflags)
@@ -121,264 +101,167 @@ dupit(fd, fp, lockflags)
        u.u_ofile[fd] = fp;
        u.u_pofile[fd] = lockflags;
        fp->f_count++;
        u.u_ofile[fd] = fp;
        u.u_pofile[fd] = lockflags;
        fp->f_count++;
+/* THIS DOESN'T BELONG HERE */
        if (lockflags&UF_SHLOCK)
        if (lockflags&UF_SHLOCK)
-               fp->f_inode->i_shlockc++;
+               ((struct inode *)fp->f_data)->i_shlockc++;
        if (lockflags&UF_EXLOCK)
        if (lockflags&UF_EXLOCK)
-               fp->f_inode->i_exlockc++;
+               ((struct inode *)fp->f_data)->i_exlockc++;
+/* END DOESN'T BELONG */
 }
 
 }
 
-close()
+/*
+ * The file control system call.
+ */
+fcntl()
 {
 {
-       register struct a {
-               int     i;
-       } *uap = (struct a *)u.u_ap;
        register struct file *fp;
        register struct file *fp;
-
-       fp = getf(uap->i);
-       if (fp == 0)
-               return;
-       if (u.u_pofile[uap->i] & UF_MAPPED)
-               munmapfd(uap->i);
-       closef(fp, 0, u.u_pofile[uap->i]);
-       /* WHAT IF u.u_error ? */
-       u.u_ofile[uap->i] = NULL;
-       u.u_pofile[uap->i] = 0;
-}
-
-wrap()
-{
        register struct a {
        register struct a {
-               int     d;
-               struct  dtype *dtypeb;
-       } *uap = (struct a *)u.u_ap;
-       register struct file *fp;
-       struct dtype adtype;
+               int     fdes;
+               int     cmd;
+               int     arg;
+       } *uap;
+       register i;
+       register char *pop;
 
 
-       fp = getf(uap->d);
-       if (fp == 0)
-               return;
-       u.u_error = copyin((caddr_t)uap->dtypeb, (caddr_t)&adtype,
-           sizeof (struct dtype));
-       if (u.u_error)
+       uap = (struct a *)u.u_ap;
+       fp = getf(uap->fdes);
+       if (fp == NULL)
                return;
                return;
-       /* DO WRAP */
-}
-
-int    unselect();
-int    nselcoll;
-/*
- * Select system call.
- */
-select()
-{
-       register struct uap  {
-               int     nd;
-               long    *in;
-               long    *ou;
-               long    *ex;
-               struct  timeval *tv;
-       } *uap = (struct uap *)u.u_ap;
-       int ibits[3], obits[3];
-       struct timeval atv;
-       int s, ncoll;
-       label_t lqsave;
-
-       obits[0] = obits[1] = obits[2] = 0;
-       if (uap->nd > NOFILE)
-               uap->nd = NOFILE;       /* forgiving, if slightly wrong */
-
-#define        getbits(name, x) \
-       if (uap->name) { \
-               u.u_error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \
-                   sizeof (ibits[x])); \
-               if (u.u_error) \
-                       goto done; \
-       } else \
-               ibits[x] = 0;
-       getbits(in, 0);
-       getbits(ou, 1);
-       getbits(ex, 2);
-#undef getbits
-
-       if (uap->tv) {
-               u.u_error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
-                       sizeof (atv));
-               if (u.u_error)
-                       goto done;
-               if (itimerfix(&atv)) {
+       pop = &u.u_pofile[uap->fdes];
+       switch(uap->cmd) {
+       case 0:
+               i = uap->arg;
+               if (i < 0 || i > NOFILE) {
                        u.u_error = EINVAL;
                        u.u_error = EINVAL;
-                       goto done;
-               }
-               s = spl7(); timevaladd(&atv, &time); splx(s);
-       }
-retry:
-       ncoll = nselcoll;
-       u.u_procp->p_flag |= SSEL;
-       u.u_r.r_val1 = selscan(ibits, obits);
-       if (u.u_error || u.u_r.r_val1)
-               goto done;
-       s = spl6();
-       if (uap->tv && timercmp(&time, &atv, >=)) {
-               splx(s);
-               goto done;
-       }
-       if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) {
-               u.u_procp->p_flag &= ~SSEL;
-               splx(s);
-               goto retry;
-       }
-       u.u_procp->p_flag &= ~SSEL;
-       if (uap->tv) {
-               lqsave = u.u_qsave;
-               if (setjmp(&u.u_qsave)) {
-                       untimeout(unselect, (caddr_t)u.u_procp);
-                       u.u_error = EINTR;
-                       splx(s);
-                       goto done;
+                       return;
                }
                }
-               timeout(unselect, (caddr_t)u.u_procp, hzto(&atv));
-       }
-       sleep((caddr_t)&selwait, PZERO+1);
-       if (uap->tv) {
-               u.u_qsave = lqsave;
-               untimeout(unselect, (caddr_t)u.u_procp);
-       }
-       splx(s);
-       goto retry;
-done:
-#define        putbits(name, x) \
-       if (uap->name) { \
-               int error = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \
-                   sizeof (obits[x])); \
-               if (error) \
-                       u.u_error = error; \
-       }
-       putbits(in, 0);
-       putbits(ou, 1);
-       putbits(ex, 2);
-#undef putbits
-}
+               if ((i = ufalloc(i)) < 0)
+                       return;
+               dupit(i, fp, *pop);
+               break;
 
 
-unselect(p)
-       register struct proc *p;
-{
-       register int s = spl6();
+       case 1:
+               u.u_r.r_val1 = *pop & 1;
+               break;
 
 
-       switch (p->p_stat) {
+       case 2:
+               *pop = (*pop &~ 1) | (uap->arg & 1);
+               break;
 
 
-       case SSLEEP:
-               setrun(p);
+       case 3:
+               u.u_r.r_val1 = fp->f_flag+FOPEN;
                break;
 
                break;
 
-       case SSTOP:
-               unsleep(p);
+       case 4:
+               fp->f_flag &= FCNTLCANT;
+               fp->f_flag |= (uap->arg-FOPEN) &~ FCNTLCANT;
+               u.u_error = fset(fp, FNDELAY, fp->f_flag & FNDELAY);
+               if (u.u_error)
+                       break;
+               u.u_error = fset(fp, FASYNC, fp->f_flag & FASYNC);
+               if (u.u_error)
+                       (void) fset(fp, FNDELAY, 0);
                break;
                break;
+
+       case 5:
+               u.u_error = fsetown(fp, uap->arg);
+               break;
+
+       case 6:
+               u.u_error = fgetown(fp, &u.u_r.r_val1);
+               break;
+
+       default:
+               u.u_error = EINVAL;
        }
        }
-       splx(s);
 }
 
 }
 
-selscan(ibits, obits)
-       int *ibits, *obits;
-{
-       register int which, bits, i;
-       int flag;
+fset(fp, bit, value)
        struct file *fp;
        struct file *fp;
-       int able;
-       struct inode *ip;
-       int n = 0;
+       int bit, value;
+{
 
 
-       for (which = 0; which < 3; which++) {
-               bits = ibits[which];
-               obits[which] = 0;
-               switch (which) {
+       if (value)
+               fp->f_flag |= bit;
+       else
+               fp->f_flag &= ~bit;
+       return (fioctl(fp, (int)(bit == FNDELAY ? FIONBIO : FIOASYNC),
+           (caddr_t)&value));
+}
 
 
-               case 0:
-                       flag = FREAD; break;
+fgetown(fp, valuep)
+       struct file *fp;
+       int *valuep;
+{
+       int error;
 
 
-               case 1:
-                       flag = FWRITE; break;
+       switch (fp->f_type) {
 
 
-               case 2:
-                       flag = 0; break;
-               }
-               while (i = ffs(bits)) {
-                       bits &= ~(1<<(i-1));
-                       fp = u.u_ofile[i-1];
-                       if (fp == NULL) {
-                               u.u_error = EBADF;
-                               break;
-                       }
-                       if (fp->f_type == DTYPE_SOCKET)
-                               able = soselect(fp->f_socket, flag);
-                       else {
-                               ip = fp->f_inode;
-                               switch (ip->i_mode & IFMT) {
-
-                               case IFCHR:
-                                       able =
-                                           (*cdevsw[major(ip->i_rdev)].d_select)
-                                               (ip->i_rdev, flag);
-                                       break;
-
-                               case IFBLK:
-                               case IFREG:
-                               case IFDIR:
-                                       able = 1;
-                                       break;
-                               }
-
-                       }
-                       if (able) {
-                               obits[which] |= (1<<(i-1));
-                               n++;
-                       }
-               }
+       case DTYPE_SOCKET:
+               *valuep = ((struct socket *)fp->f_data)->so_pgrp;
+               return (0);
+
+       default:
+               error = fioctl(fp, (int)TIOCGPGRP, (caddr_t)valuep);
+               *valuep = -*valuep;
+               return (error);
        }
        }
-       return (n);
 }
 
 }
 
-/*ARGSUSED*/
-seltrue(dev, flag)
-       dev_t dev;
-       int flag;
+fsetown(fp, value)
+       struct file *fp;
+       int value;
 {
 
 {
 
-       return (1);
+       if (fp->f_type == DTYPE_SOCKET) {
+               ((struct socket *)fp->f_data)->so_pgrp = value;
+               return (0);
+       }
+       if (value > 0) {
+               struct proc *p = pfind(value);
+               if (p == 0)
+                       return (EINVAL);
+               value = p->p_pgrp;
+       } else
+               value = -value;
+       return (fioctl(fp, (int)TIOCSPGRP, (caddr_t)&value));
 }
 
 }
 
-selwakeup(p, coll)
-       register struct proc *p;
-       int coll;
+fioctl(fp, cmd, value)
+       struct file *fp;
+       int cmd;
+       caddr_t value;
 {
 
 {
 
-       if (coll) {
-               nselcoll++;
-               wakeup((caddr_t)&selwait);
-       }
-       if (p) {
-               int s = spl6();
-               if (p->p_wchan == (caddr_t)&selwait)
-                       setrun(p);
-               else if (p->p_flag & SSEL)
-                       p->p_flag &= ~SSEL;
-               splx(s);
-       }
+       return ((*fp->f_ops->fo_ioctl)(fp, cmd, value));
 }
 
 }
 
-revoke()
+close()
 {
 {
+       register struct a {
+               int     i;
+       } *uap = (struct a *)u.u_ap;
+       register struct file *fp;
 
 
-       /* XXX */
+       fp = getf(uap->i);
+       if (fp == 0)
+               return;
+       if (u.u_pofile[uap->i] & UF_MAPPED)
+               munmapfd(uap->i);
+       closef(fp, u.u_pofile[uap->i]);
+       /* WHAT IF u.u_error ? */
+       u.u_ofile[uap->i] = NULL;
+       u.u_pofile[uap->i] = 0;
 }
 
 /*
  * Allocate a user file descriptor.
  */
 }
 
 /*
  * Allocate a user file descriptor.
  */
-ufalloc()
+ufalloc(i)
+       register int i;
 {
 {
-       register i;
 
 
-       for (i=0; i<NOFILE; i++)
+       for (; i < NOFILE; i++)
                if (u.u_ofile[i] == NULL) {
                        u.u_r.r_val1 = i;
                        u.u_pofile[i] = 0;
                if (u.u_ofile[i] == NULL) {
                        u.u_r.r_val1 = i;
                        u.u_pofile[i] = 0;
@@ -388,6 +271,16 @@ ufalloc()
        return (-1);
 }
 
        return (-1);
 }
 
+ufavail()
+{
+       register int i, avail = 0;
+
+       for (i = 0; i < NOFILE; i++)
+               if (u.u_ofile[i] == NULL)
+                       avail++;
+       return (avail);
+}
+
 struct file *lastf;
 /*
  * Allocate a user file descriptor
 struct file *lastf;
 /*
  * Allocate a user file descriptor
@@ -401,7 +294,7 @@ falloc()
        register struct file *fp;
        register i;
 
        register struct file *fp;
        register i;
 
-       i = ufalloc();
+       i = ufalloc(0);
        if (i < 0)
                return (NULL);
        if (lastf == 0)
        if (i < 0)
                return (NULL);
        if (lastf == 0)
@@ -417,16 +310,17 @@ falloc()
        return (NULL);
 slot:
        u.u_ofile[i] = fp;
        return (NULL);
 slot:
        u.u_ofile[i] = fp;
-       fp->f_count++;
+       fp->f_count = 1;
+       fp->f_data = 0;
        fp->f_offset = 0;
        fp->f_offset = 0;
-       fp->f_inode = 0;
        lastf = fp + 1;
        return (fp);
 }
        lastf = fp + 1;
        return (fp);
 }
+
 /*
  * Convert a user supplied file descriptor into a pointer
  * to a file structure.  Only task is to check range of the descriptor.
 /*
  * Convert a user supplied file descriptor into a pointer
  * to a file structure.  Only task is to check range of the descriptor.
- * Critical paths should use the GETF macro, defined in inline.h.
+ * Critical paths should use the GETF macro.
  */
 struct file *
 getf(f)
  */
 struct file *
 getf(f)
@@ -443,94 +337,26 @@ getf(f)
 
 /*
  * Internal form of close.
 
 /*
  * Internal form of close.
- * Decrement reference count on
- * file structure.
- * Also make sure the pipe protocol
- * does not constipate.
- *
- * Decrement reference count on the inode following
- * removal to the referencing file structure.
- * Call device handler on last close.
- * Nouser indicates that the user isn't available to present
- * errors to.
- *
- * Handling locking at this level is RIDICULOUS.
+ * Decrement reference count on file structure.
+ * If last reference not going away, but no more
+ * references except in message queues, run a
+ * garbage collect.  This would better be done by
+ * forcing a gc() to happen sometime soon, rather
+ * than running one each time.
  */
  */
-closef(fp, nouser, flags)
+closef(fp, flags)
        register struct file *fp;
        register struct file *fp;
-       int nouser, flags;
+       int flags;                                      /* XXX */
 {
 {
-       register struct inode *ip;
-       register struct mount *mp;
-       int flag, mode;
-       dev_t dev;
-       register int (*cfunc)();
 
        if (fp == NULL)
                return;
        if (fp->f_count > 1) {
                fp->f_count--;
 
        if (fp == NULL)
                return;
        if (fp->f_count > 1) {
                fp->f_count--;
+               if (fp->f_count == fp->f_msgcount)
+                       unp_gc();
                return;
        }
                return;
        }
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = soclose(fp->f_socket, nouser);
-               if (nouser == 0 && u.u_error)
-                       return;
-               fp->f_socket = 0;
-               fp->f_count = 0;
-               return;
-       }
-       flag = fp->f_flag;
-       ip = fp->f_inode;
-       dev = (dev_t)ip->i_rdev;
-       mode = ip->i_mode & IFMT;
-       flags &= UF_SHLOCK|UF_EXLOCK;                   /* conservative */
-       if (flags)
-               funlocki(ip, flags);
-       ilock(ip);
-       iput(ip);
+       (*fp->f_ops->fo_close)(fp, flags);
        fp->f_count = 0;
        fp->f_count = 0;
-
-       switch (mode) {
-
-       case IFCHR:
-               cfunc = cdevsw[major(dev)].d_close;
-               break;
-
-       case IFBLK:
-               /*
-                * We don't want to really close the device if it is mounted
-                */
-               for (mp = mount; mp < &mount[NMOUNT]; mp++)
-                       if (mp->m_bufp != NULL && mp->m_dev == dev)
-                               return;
-               cfunc = bdevsw[major(dev)].d_close;
-               break;
-
-       default:
-               return;
-       }
-       for (fp = file; fp < fileNFILE; fp++) {
-               if (fp->f_type == DTYPE_SOCKET)         /* XXX */
-                       continue;
-               if (fp->f_count && (ip = fp->f_inode) &&
-                   ip->i_rdev == dev && (ip->i_mode&IFMT) == mode)
-                       return;
-       }
-       if (mode == IFBLK) {
-               /*
-                * On last close of a block device (that isn't mounted)
-                * we must invalidate any in core blocks
-                */
-               bflush(dev);
-               binval(dev);
-       }
-       (*cfunc)(dev, flag, fp);
-}
-
-opause()
-{
-
-       for (;;)
-               sleep((caddr_t)&u, PSLEP);
 }
 }
index 80ba6aa..0363ade 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_proc.c     4.63    83/05/21        */
+/*     kern_proc.c     4.64    83/05/27        */
 
 #include "../machine/reg.h"
 #include "../machine/pte.h"
 
 #include "../machine/reg.h"
 #include "../machine/pte.h"
 #include "../h/text.h"
 #include "../h/file.h"
 #include "../h/quota.h"
 #include "../h/text.h"
 #include "../h/file.h"
 #include "../h/quota.h"
-#include "../h/descrip.h"
 #include "../h/uio.h"
 #include "../h/mbuf.h"
 #include "../h/nami.h"
 
 #include "../h/uio.h"
 #include "../h/mbuf.h"
 #include "../h/nami.h"
 
-gethostid()
-{
-
-       u.u_r.r_val1 = hostid;
-}
-
-sethostid()
-{
-       struct a {
-               int     hostid;
-       } *uap = (struct a *)u.u_ap;
-
-       if (suser())
-               hostid = uap->hostid;
-}
-
-gethostname()
-{
-       register struct a {
-               char    *hostname;
-               int     len;
-       } *uap = (struct a *)u.u_ap;
-       register u_int len;
-
-       len = uap->len;
-       if (len > hostnamelen + 1)
-               len = hostnamelen + 1;
-       u.u_error = copyout((caddr_t)hostname, (caddr_t)uap->hostname, len);
-}
-
-sethostname()
-{
-       register struct a {
-               char    *hostname;
-               u_int   len;
-       } *uap = (struct a *)u.u_ap;
-
-       if (!suser())
-               return;
-       if (uap->len > sizeof (hostname) - 1) {
-               u.u_error = EINVAL;
-               return;
-       }
-       hostnamelen = uap->len;
-       u.u_error = copyin((caddr_t)uap->hostname, hostname, uap->len);
-       hostname[hostnamelen] = 0;
-}
-
-/*
- * exec system call, with and without environments.
- */
-struct execa {
-       char    *fname;
-       char    **argp;
-       char    **envp;
-};
-
-execv()
-{
-       ((struct execa *)u.u_ap)->envp = NULL;
-       execve();
-}
-
-execve()
-{
-       register nc;
-       register char *cp;
-       register struct buf *bp;
-       register struct execa *uap;
-       int na, ne, ucp, ap, c;
-       int indir, uid, gid;
-       char *sharg;
-       struct inode *ip;
-       swblk_t bno;
-       char cfname[MAXCOMLEN + 1];
-       char cfarg[SHSIZE];
-       int resid;
-
-       if ((ip = namei(uchar, LOOKUP, 1)) == NULL)
-               return;
-       bno = 0;
-       bp = 0;
-       indir = 0;
-       uid = u.u_uid;
-       gid = u.u_gid;
-       if (ip->i_mode & ISUID)
-               uid = ip->i_uid;
-       if (ip->i_mode & ISGID)
-               gid = ip->i_gid;
-
-  again:
-       if (access(ip, IEXEC))
-               goto bad;
-       if ((u.u_procp->p_flag&STRC) && access(ip, IREAD))
-               goto bad;
-       if ((ip->i_mode & IFMT) != IFREG ||
-          (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) {
-               u.u_error = EACCES;
-               goto bad;
-       }
-
-       /*
-        * Read in first few bytes of file for segment sizes, ux_mag:
-        *      407 = plain executable
-        *      410 = RO text
-        *      413 = demand paged RO text
-        * Also an ASCII line beginning with #! is
-        * the file name of a ``shell'' and arguments may be prepended
-        * to the argument list if given here.
-        *
-        * SHELL NAMES ARE LIMITED IN LENGTH.
-        *
-        * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
-        * THE ASCII LINE.
-        */
-       u.u_exdata.ux_shell[0] = 0;     /* for zero length files */
-       u.u_error = rdwri(UIO_READ, ip, (caddr_t)&u.u_exdata, sizeof (u.u_exdata),
-           0, 1, &resid);
-       if (u.u_error)
-               goto bad;
-       u.u_count = resid;
-#ifndef lint
-       if (u.u_count > sizeof(u.u_exdata) - sizeof(u.u_exdata.Ux_A) &&
-           u.u_exdata.ux_shell[0] != '#') {
-               u.u_error = ENOEXEC;
-               goto bad;
-       }
-#endif
-       switch (u.u_exdata.ux_mag) {
-
-       case 0407:
-               u.u_exdata.ux_dsize += u.u_exdata.ux_tsize;
-               u.u_exdata.ux_tsize = 0;
-               break;
-
-       case 0413:
-       case 0410:
-               if (u.u_exdata.ux_tsize == 0) {
-                       u.u_error = ENOEXEC;
-                       goto bad;
-               }
-               break;
-
-       default:
-               if (u.u_exdata.ux_shell[0] != '#' ||
-                   u.u_exdata.ux_shell[1] != '!' ||
-                   indir) {
-                       u.u_error = ENOEXEC;
-                       goto bad;
-               }
-               cp = &u.u_exdata.ux_shell[2];           /* skip "#!" */
-               while (cp < &u.u_exdata.ux_shell[SHSIZE]) {
-                       if (*cp == '\t')
-                               *cp = ' ';
-                       else if (*cp == '\n') {
-                               *cp = '\0';
-                               break;
-                       }
-                       cp++;
-               }
-               if (*cp != '\0') {
-                       u.u_error = ENOEXEC;
-                       goto bad;
-               }
-               cp = &u.u_exdata.ux_shell[2];
-               while (*cp == ' ')
-                       cp++;
-               u.u_dirp = cp;
-               while (*cp && *cp != ' ')
-                       cp++;
-               sharg = NULL;
-               if (*cp) {
-                       *cp++ = '\0';
-                       while (*cp == ' ')
-                               cp++;
-                       if (*cp) {
-                               bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE);
-                               sharg = cfarg;
-                       }
-               }
-               if (u.u_dent.d_namlen > MAXCOMLEN)
-                       u.u_dent.d_namlen = MAXCOMLEN;
-               bcopy((caddr_t)u.u_dent.d_name, (caddr_t)cfname,
-                   (unsigned)(u.u_dent.d_namlen + 1));
-               cfname[MAXCOMLEN] = 0;
-               indir = 1;
-               iput(ip);
-               ip = namei(schar, LOOKUP, 1);
-               if (ip == NULL)
-                       return;
-               goto again;
-       }
-
-       /*
-        * Collect arguments on "file" in swap space.
-        */
-       na = 0;
-       ne = 0;
-       nc = 0;
-       uap = (struct execa *)u.u_ap;
-       if ((bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS))))) == 0) {
-               swkill(u.u_procp, "exece");
-               goto bad;
-       }
-       if (bno % CLSIZE)
-               panic("execa rmalloc");
-       if (uap->argp) for (;;) {
-               ap = NULL;
-               if (indir && (na == 1 || na == 2 && sharg))
-                       ap = (int)uap->fname;
-               else if (uap->argp) {
-                       ap = fuword((caddr_t)uap->argp);
-                       uap->argp++;
-               }
-               if (ap==NULL && uap->envp) {
-                       uap->argp = NULL;
-                       if ((ap = fuword((caddr_t)uap->envp)) == NULL)
-                               break;
-                       uap->envp++;
-                       ne++;
-               }
-               if (ap == NULL)
-                       break;
-               na++;
-               if (ap == -1)
-                       u.u_error = EFAULT;
-               do {
-                       if (nc >= NCARGS-1)
-                               u.u_error = E2BIG;
-                       if (indir && na == 2 && sharg != NULL)
-                               c = *sharg++ & 0377;
-                       else if ((c = fubyte((caddr_t)ap++)) < 0)
-                               u.u_error = EFAULT;
-                       if (u.u_error) {
-                               if (bp)
-                                       brelse(bp);
-                               bp = 0;
-                               goto badarg;
-                       }
-                       if (nc % (CLSIZE*NBPG) == 0) {
-                               if (bp)
-                                       bdwrite(bp);
-                               bp = getblk(argdev, bno + ctod(nc / NBPG),
-                                   CLSIZE*NBPG);
-                               cp = bp->b_un.b_addr;
-                       }
-                       nc++;
-                       *cp++ = c;
-               } while (c > 0);
-       }
-       if (bp)
-               bdwrite(bp);
-       bp = 0;
-       nc = (nc + NBPW-1) & ~(NBPW-1);
-       if (indir) {
-               u.u_dent.d_namlen = strlen(cfname);
-               bcopy((caddr_t)cfname, (caddr_t)u.u_dent.d_name,
-                   (unsigned)(u.u_dent.d_namlen + 1));
-       }
-       getxfile(ip, nc + (na+4)*NBPW, uid, gid);
-       if (u.u_error) {
-badarg:
-               for (c = 0; c < nc; c += CLSIZE*NBPG) {
-                       bp = baddr(argdev, bno + ctod(c / NBPG), CLSIZE*NBPG);
-                       if (bp) {
-                               bp->b_flags |= B_AGE;           /* throw away */
-                               bp->b_flags &= ~B_DELWRI;       /* cancel io */
-                               brelse(bp);
-                               bp = 0;
-                       }
-               }
-               goto bad;
-       }
-
-       /*
-        * copy back arglist
-        */
-       ucp = USRSTACK - nc - NBPW;
-       ap = ucp - na*NBPW - 3*NBPW;
-       u.u_ar0[SP] = ap;
-       (void) suword((caddr_t)ap, na-ne);
-       nc = 0;
-       for (;;) {
-               ap += NBPW;
-               if (na==ne) {
-                       (void) suword((caddr_t)ap, 0);
-                       ap += NBPW;
-               }
-               if (--na < 0)
-                       break;
-               (void) suword((caddr_t)ap, ucp);
-               do {
-                       if (nc % (CLSIZE*NBPG) == 0) {
-                               if (bp)
-                                       brelse(bp);
-                               bp = bread(argdev, bno + ctod(nc / NBPG),
-                                   CLSIZE*NBPG);
-                               bp->b_flags |= B_AGE;           /* throw away */
-                               bp->b_flags &= ~B_DELWRI;       /* cancel io */
-                               cp = bp->b_un.b_addr;
-                       }
-                       (void) subyte((caddr_t)ucp++, (c = *cp++));
-                       nc++;
-               } while(c&0377);
-       }
-       (void) suword((caddr_t)ap, 0);
-       setregs();
-bad:
-       if (bp)
-               brelse(bp);
-       if (bno)
-               rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno);
-       iput(ip);
-}
-
-/*
- * Read in and set up memory for executed file.
- */
-getxfile(ip, nargc, uid, gid)
-register struct inode *ip;
-{
-       register size_t ts, ds, ss;
-       int pagi;
-
-       if (u.u_exdata.ux_mag == 0413)
-               pagi = SPAGI;
-       else
-               pagi = 0;
-       if (u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 &&
-           ip->i_count!=1) {
-               register struct file *fp;
-
-               for (fp = file; fp < fileNFILE; fp++) {
-                       if (fp->f_type == DTYPE_FILE &&
-                           fp->f_count > 0 &&
-                           fp->f_inode == ip && (fp->f_flag&FWRITE)) {
-                               u.u_error = ETXTBSY;
-                               goto bad;
-                       }
-               }
-       }
-
-       /*
-        * Compute text and data sizes and make sure not too large.
-        */
-       ts = clrnd(btoc(u.u_exdata.ux_tsize));
-       ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize)));
-       ss = clrnd(SSIZE + btoc(nargc));
-       if (chksize(ts, ds, ss))
-               goto bad;
-
-       /*
-        * Make sure enough space to start process.
-        */
-       u.u_cdmap = zdmap;
-       u.u_csmap = zdmap;
-       if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL)
-               goto bad;
-
-       /*
-        * At this point, committed to the new image!
-        * Release virtual memory resources of old process, and
-        * initialize the virtual memory of the new process.
-        * If we resulted from vfork(), instead wakeup our
-        * parent who will set SVFDONE when he has taken back
-        * our resources.
-        */
-       if ((u.u_procp->p_flag & SVFORK) == 0)
-               vrelvm();
-       else {
-               u.u_procp->p_flag &= ~SVFORK;
-               u.u_procp->p_flag |= SKEEP;
-               wakeup((caddr_t)u.u_procp);
-               while ((u.u_procp->p_flag & SVFDONE) == 0)
-                       sleep((caddr_t)u.u_procp, PZERO - 1);
-               u.u_procp->p_flag &= ~(SVFDONE|SKEEP);
-       }
-       u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SNUSIG);
-       u.u_procp->p_flag |= pagi;
-       u.u_dmap = u.u_cdmap;
-       u.u_smap = u.u_csmap;
-       vgetvm(ts, ds, ss);
-
-       if (pagi == 0)
-               u.u_error =
-                   rdwri(UIO_READ, ip,
-                       (char *)ctob(dptov(u.u_procp, 0)),
-                       (int)u.u_exdata.ux_dsize,
-                       (int)(sizeof(u.u_exdata)+u.u_exdata.ux_tsize),
-                       0, (int *)0);
-       xalloc(ip, pagi);
-       if (pagi && u.u_procp->p_textp)
-               vinifod((struct fpte *)dptopte(u.u_procp, 0),
-                   PG_FTEXT, u.u_procp->p_textp->x_iptr,
-                   (long)(1 + ts/CLSIZE), (int)btoc(u.u_exdata.ux_dsize));
-
-#ifdef vax
-       /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
-#include "../vax/mtpr.h"               /* XXX */
-       mtpr(TBIA, 0);
-#endif
-
-       if (u.u_error)
-               swkill(u.u_procp, "i/o error mapping pages");
-       /*
-        * set SUID/SGID protections, if no tracing
-        */
-       if ((u.u_procp->p_flag&STRC)==0) {
-               u.u_uid = uid;
-               u.u_procp->p_uid = uid;
-               u.u_gid = gid;
-       } else
-               psignal(u.u_procp, SIGTRAP);
-       u.u_tsize = ts;
-       u.u_dsize = ds;
-       u.u_ssize = ss;
-bad:
-       return;
-}
-
-/*
- * Clear registers on exec
- */
-setregs()
-{
-       register int (**rp)();
-       register i;
-       long sigmask;
-
-       for (rp = &u.u_signal[1], sigmask = 1L; rp < &u.u_signal[NSIG];
-           sigmask <<= 1, rp++) {
-               switch (*rp) {
-
-               case SIG_IGN:
-               case SIG_DFL:
-               case SIG_HOLD:
-                       continue;
-
-               default:
-                       /*
-                        * Normal or deferring catch; revert to default.
-                        */
-                       (void) spl6();
-                       *rp = SIG_DFL;
-                       if ((int)*rp & 1)
-                               u.u_procp->p_siga0 |= sigmask;
-                       else
-                               u.u_procp->p_siga0 &= ~sigmask;
-                       if ((int)*rp & 2)
-                               u.u_procp->p_siga1 |= sigmask;
-                       else
-                               u.u_procp->p_siga1 &= ~sigmask;
-                       (void) spl0();
-                       continue;
-               }
-       }
-#ifdef vax
-/*
-       for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
-               *rp++ = 0;
-*/
-       u.u_ar0[PC] = u.u_exdata.ux_entloc+2;
-#endif
-#ifdef sun
-       { register struct regs *r = (struct regs *)u.u_ar0;
-         for (i = 0; i < 8; i++) {
-               r->r_dreg[i] = 0;
-               if (&r->r_areg[i] != &r->r_sp)
-                       r->r_areg[i] = 0;
-         }
-         r->r_sr = PSL_USERSET;
-         r->r_pc = u.u_exdata.ux_entloc;
-       }
-#endif
-       for (i=0; i<NOFILE; i++) {
-               if (u.u_pofile[i]&UF_EXCLOSE) {
-                       closef(u.u_ofile[i], 1, u.u_pofile[i]);
-                       u.u_ofile[i] = NULL;
-                       u.u_pofile[i] = 0;
-               }
-               u.u_pofile[i] &= ~UF_MAPPED;
-       }
-
-       /*
-        * Remember file name for accounting.
-        */
-       u.u_acflag &= ~AFORK;
-       bcopy((caddr_t)u.u_dent.d_name, (caddr_t)u.u_comm,
-           (unsigned)(u.u_dent.d_namlen + 1));
-#ifdef sun
-       u.u_eosys = REALLYRETURN;
-#endif
-}
-
-/*
- * Exit system call: pass back caller's arg
- */
-rexit()
-{
-       register struct a {
-               int     rval;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       exit((uap->rval & 0377) << 8);
-}
-
-/*
- * Release resources.
- * Save u. area for parent to look at.
- * Enter zombie state.
- * Wake up parent and init processes,
- * and dispose of children.
- */
-exit(rv)
-{
-       register int i;
-       register struct proc *p, *q;
-       register int x;
-       struct mbuf *m = m_getclr(M_WAIT, MT_ZOMBIE);
-
-#ifdef PGINPROF
-       vmsizmon();
-#endif
-       p = u.u_procp;
-       p->p_flag &= ~(STRC|SULOCK);
-       p->p_flag |= SWEXIT;
-       (void) spl6();
-       if ((int)SIG_IGN & 1)
-               p->p_siga0 = ~0;
-       else
-               p->p_siga0 = 0;
-       if ((int)SIG_IGN & 2)
-               p->p_siga1 = ~0;
-       else
-               p->p_siga1 = 0;
-       (void) spl0();
-       p->p_cpticks = 0;
-       p->p_pctcpu = 0;
-       for (i=0; i<NSIG; i++)
-               u.u_signal[i] = SIG_IGN;
-       untimeout(realitexpire, (caddr_t)p);
-       /*
-        * Release virtual memory.  If we resulted from
-        * a vfork(), instead give the resources back to
-        * the parent.
-        */
-       if ((p->p_flag & SVFORK) == 0)
-               vrelvm();
-       else {
-               p->p_flag &= ~SVFORK;
-               wakeup((caddr_t)p);
-               while ((p->p_flag & SVFDONE) == 0)
-                       sleep((caddr_t)p, PZERO - 1);
-               p->p_flag &= ~SVFDONE;
-       }
-       for (i = 0; i < NOFILE; i++) {
-               struct file *f;
-               int p;
-
-               f = u.u_ofile[i];
-               u.u_ofile[i] = NULL;
-               p = u.u_pofile[i];
-               u.u_pofile[i] = 0;
-               closef(f, 1, p);
-       }
-       ilock(u.u_cdir);
-       iput(u.u_cdir);
-       if (u.u_rdir) {
-               ilock(u.u_rdir);
-               iput(u.u_rdir);
-       }
-       u.u_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
-       acct();
-#ifdef QUOTA
-       qclean();
-#endif
-#ifdef sun
-       ctxfree(u.u_procp);
-#endif
-       vrelpt(u.u_procp);
-       vrelu(u.u_procp, 0);
-       (void) spl5();          /* hack for mem alloc race XXX */
-       multprog--;
-       p->p_stat = SZOMB;
-       noproc = 1;
-       i = PIDHASH(p->p_pid);
-       x = p - proc;
-       if (pidhash[i] == x)
-               pidhash[i] = p->p_idhash;
-       else {
-               for (i = pidhash[i]; i != 0; i = proc[i].p_idhash)
-                       if (proc[i].p_idhash == x) {
-                               proc[i].p_idhash = p->p_idhash;
-                               goto done;
-                       }
-               panic("exit");
-       }
-       if (p->p_pid == 1)
-               panic("init died");
-done:
-       p->p_xstat = rv;
-if (m == 0)
-panic("exit: m_getclr");
-       p->p_ru = mtod(m, struct rusage *);
-       *p->p_ru = u.u_ru;
-       ruadd(p->p_ru, &u.u_cru);
-       for (q = proc; q < procNPROC; q++)
-               if (q->p_pptr == p) {
-                       if (q->p_osptr)
-                               q->p_osptr->p_ysptr = q->p_ysptr;
-                       if (q->p_ysptr)
-                               q->p_ysptr->p_osptr = q->p_osptr;
-                       if (proc[1].p_cptr)
-                               proc[1].p_cptr->p_ysptr = q;
-                       q->p_osptr = proc[1].p_cptr;
-                       q->p_ysptr = NULL;
-                       proc[1].p_cptr = q;
-
-                       q->p_pptr = &proc[1];
-                       q->p_ppid = 1;
-                       wakeup((caddr_t)&proc[1]);
-                       /*
-                        * Traced processes are killed
-                        * since their existence means someone is screwing up.
-                        * Stopped processes are sent a hangup and a continue.
-                        * This is designed to be ``safe'' for setuid
-                        * processes since they must be willing to tolerate
-                        * hangups anyways.
-                        */
-                       if (q->p_flag&STRC) {
-                               q->p_flag &= ~STRC;
-                               psignal(q, SIGKILL);
-                       } else if (q->p_stat == SSTOP) {
-                               psignal(q, SIGHUP);
-                               psignal(q, SIGCONT);
-                       }
-                       /*
-                        * Protect this process from future
-                        * tty signals, clear TSTP/TTIN/TTOU if pending.
-                        */
-                       (void) spgrp(q, -1);
-               }
-       psignal(p->p_pptr, SIGCHLD);
-       wakeup((caddr_t)p->p_pptr);
-       swtch();
-}
-
-wait()
-{
-       struct rusage ru, *rup;
-
-       if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) {
-               u.u_error = wait1(0, (struct rusage *)0);
-               return;
-       }
-       rup = (struct rusage *)u.u_ar0[R1];
-       u.u_error = wait1(u.u_ar0[R0], &ru);
-       if (u.u_error)
-               return;
-       (void) copyout((caddr_t)&ru, (caddr_t)rup, sizeof (struct rusage));
-}
-
-#ifndef NOCOMPAT
-#include "../h/vtimes.h"
-
-owait()
-{
-       struct rusage ru;
-       struct vtimes *vtp, avt;
-
-       if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) {
-               u.u_error = wait1(0, (struct rusage *)0);
-               return;
-       }
-       vtp = (struct vtimes *)u.u_ar0[R1];
-       u.u_error = wait1(u.u_ar0[R0], &ru);
-       if (u.u_error)
-               return;
-       getvtimes(&ru, &avt);
-       (void) copyout((caddr_t)&avt, (caddr_t)vtp, sizeof (struct vtimes));
-}
-#endif
-
-/*
- * Wait system call.
- * Search for a terminated (zombie) child,
- * finally lay it to rest, and collect its status.
- * Look also for stopped (traced) children,
- * and pass back status from them.
- */
-wait1(options, ru)
-       register int options;
-       struct rusage *ru;
-{
-       register f;
-       register struct proc *p, *q;
-
-       f = 0;
-loop:
-       for (p = proc; p < procNPROC; p++)
-       if (p->p_pptr == u.u_procp) {
-               f++;
-               if (p->p_stat == SZOMB) {
-                       u.u_r.r_val1 = p->p_pid;
-                       u.u_r.r_val2 = p->p_xstat;
-                       p->p_xstat = 0;
-                       if (ru)
-                               *ru = *p->p_ru;
-                       ruadd(&u.u_cru, p->p_ru);
-                       (void) m_free(dtom(p->p_ru));
-                       p->p_ru = 0;
-                       p->p_stat = NULL;
-                       p->p_pid = 0;
-                       p->p_ppid = 0;
-                       if (q = p->p_ysptr)
-                               q->p_osptr = p->p_osptr;
-                       if (q = p->p_osptr)
-                               q->p_ysptr = p->p_ysptr;
-                       if ((q = p->p_pptr)->p_cptr == p)
-                               q->p_cptr = p->p_osptr;
-                       p->p_pptr = 0;
-                       p->p_ysptr = 0;
-                       p->p_osptr = 0;
-                       p->p_cptr = 0;
-                       p->p_sig = 0;
-                       p->p_siga0 = 0;
-                       p->p_siga1 = 0;
-                       p->p_pgrp = 0;
-                       p->p_flag = 0;
-                       p->p_wchan = 0;
-                       p->p_cursig = 0;
-                       return (0);
-               }
-               if (p->p_stat == SSTOP && (p->p_flag&SWTED)==0 &&
-                   (p->p_flag&STRC || options&WUNTRACED)) {
-                       p->p_flag |= SWTED;
-                       u.u_r.r_val1 = p->p_pid;
-                       u.u_r.r_val2 = (p->p_cursig<<8) | WSTOPPED;
-                       return (0);
-               }
-       }
-       if (f == 0) {
-               return (ECHILD);
-       }
-       if (options&WNOHANG) {
-               u.u_r.r_val1 = 0;
-               return (0);
-       }
-       if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) {
-               u.u_eosys = RESTARTSYS;
-               return (0);
-       }
-       sleep((caddr_t)u.u_procp, PWAIT);
-       goto loop;
-}
-
-/*
- * fork system call.
- */
-fork()
-{
-
-       u.u_cdmap = zdmap;
-       u.u_csmap = zdmap;
-       if (swpexpand(u.u_dsize, u.u_ssize, &u.u_cdmap, &u.u_csmap) == 0) {
-               u.u_r.r_val2 = 0;
-               return;
-       }
-       fork1(0);
-}
-
-fork1(isvfork)
-{
-       register struct proc *p1, *p2;
-       register a;
-
-       a = 0;
-       p2 = NULL;
-       for (p1 = proc; p1 < procNPROC; p1++) {
-               if (p1->p_stat==NULL && p2==NULL)
-                       p2 = p1;
-               else {
-                       if (p1->p_uid==u.u_uid && p1->p_stat!=NULL)
-                               a++;
-               }
-       }
-       /*
-        * Disallow if
-        *  No processes at all;
-        *  not su and too many procs owned; or
-        *  not su and would take last slot.
-        */
-       if (p2==NULL)
-               tablefull("proc");
-       if (p2==NULL || (u.u_uid!=0 && (p2==procNPROC-1 || a>MAXUPRC))) {
-               u.u_error = EAGAIN;
-               if (!isvfork) {
-                       (void) vsexpand(0, &u.u_cdmap, 1);
-                       (void) vsexpand(0, &u.u_csmap, 1);
-               }
-               goto out;
-       }
-       p1 = u.u_procp;
-       if (newproc(isvfork)) {
-               u.u_r.r_val1 = p1->p_pid;
-               u.u_r.r_val2 = 1;  /* child */
-               u.u_start = time.tv_sec;
-               u.u_acflag = AFORK;
-               return;
-       }
-       u.u_r.r_val1 = p2->p_pid;
-
-out:
-       u.u_r.r_val2 = 0;
-}
-
 spgrp(top, npgrp)
 spgrp(top, npgrp)
-register struct proc *top;
+       register struct proc *top;
 {
        register struct proc *pp, *p;
        int f = 0;
 {
        register struct proc *pp, *p;
        int f = 0;
@@ -900,173 +82,3 @@ pfind(pid)
                        return (p);
        return ((struct proc *)0);
 }
                        return (p);
        return ((struct proc *)0);
 }
-
-/*
- * Create a new process-- the internal version of
- * sys fork.
- * It returns 1 in the new process, 0 in the old.
- */
-newproc(isvfork)
-       int isvfork;
-{
-       register struct proc *p;
-       register struct proc *rpp, *rip;
-       register int n;
-       register struct file *fp;
-
-       p = NULL;
-       /*
-        * First, just locate a slot for a process
-        * and copy the useful info from this process into it.
-        * The panic "cannot happen" because fork has already
-        * checked for the existence of a slot.
-        */
-retry:
-       mpid++;
-       if (mpid >= 30000) {
-               mpid = 0;
-               goto retry;
-       }
-       for (rpp = proc; rpp < procNPROC; rpp++) {
-               if (rpp->p_stat == NULL && p==NULL)
-                       p = rpp;
-               if (rpp->p_pid==mpid || rpp->p_pgrp==mpid)
-                       goto retry;
-       }
-       if ((rpp = p) == NULL)
-               panic("no procs");
-
-       /*
-        * Make a proc table entry for the new process.
-        */
-       rip = u.u_procp;
-#ifdef QUOTA
-       rpp->p_quota = rip->p_quota;
-       rpp->p_quota->q_cnt++;
-#endif
-       rpp->p_stat = SIDL;
-       timerclear(&rpp->p_realtimer.it_value);
-       rpp->p_flag = SLOAD | (rip->p_flag & (SPAGI|SNUSIG));
-       if (isvfork) {
-               rpp->p_flag |= SVFORK;
-               rpp->p_ndx = rip->p_ndx;
-       } else
-               rpp->p_ndx = rpp - proc;
-       rpp->p_uid = rip->p_uid;
-       rpp->p_pgrp = rip->p_pgrp;
-       rpp->p_nice = rip->p_nice;
-       rpp->p_textp = isvfork ? 0 : rip->p_textp;
-       rpp->p_pid = mpid;
-       rpp->p_ppid = rip->p_pid;
-       rpp->p_pptr = rip;
-       rpp->p_osptr = rip->p_cptr;
-       if (rip->p_cptr)
-               rip->p_cptr->p_ysptr = rpp;
-       rpp->p_ysptr = NULL;
-       rpp->p_cptr = NULL;
-       rip->p_cptr = rpp;
-       rpp->p_time = 0;
-       rpp->p_cpu = 0;
-       rpp->p_siga0 = rip->p_siga0;
-       rpp->p_siga1 = rip->p_siga1;
-       /* take along any pending signals, like stops? */
-       if (isvfork) {
-               rpp->p_tsize = rpp->p_dsize = rpp->p_ssize = 0;
-               rpp->p_szpt = clrnd(ctopt(UPAGES));
-               forkstat.cntvfork++;
-               forkstat.sizvfork += rip->p_dsize + rip->p_ssize;
-       } else {
-               rpp->p_tsize = rip->p_tsize;
-               rpp->p_dsize = rip->p_dsize;
-               rpp->p_ssize = rip->p_ssize;
-               rpp->p_szpt = rip->p_szpt;
-               forkstat.cntfork++;
-               forkstat.sizfork += rip->p_dsize + rip->p_ssize;
-       }
-       rpp->p_rssize = 0;
-       rpp->p_maxrss = rip->p_maxrss;
-       rpp->p_wchan = 0;
-       rpp->p_slptime = 0;
-       rpp->p_pctcpu = 0;
-       rpp->p_cpticks = 0;
-       n = PIDHASH(rpp->p_pid);
-       p->p_idhash = pidhash[n];
-       pidhash[n] = rpp - proc;
-       multprog++;
-
-       /*
-        * Increase reference counts on shared objects.
-        */
-       for (n = 0; n < NOFILE; n++) {
-               fp = u.u_ofile[n];
-               if (fp == NULL)
-                       continue;
-               fp->f_count++;
-               if (u.u_pofile[n]&UF_SHLOCK)
-                       fp->f_inode->i_shlockc++;
-               if (u.u_pofile[n]&UF_EXLOCK)
-                       fp->f_inode->i_exlockc++;
-       }
-       u.u_cdir->i_count++;
-       if (u.u_rdir)
-               u.u_rdir->i_count++;
-
-       /*
-        * Partially simulate the environment
-        * of the new process so that when it is actually
-        * created (by copying) it will look right.
-        * This begins the section where we must prevent the parent
-        * from being swapped.
-        */
-       rip->p_flag |= SKEEP;
-       if (procdup(rpp, isvfork))
-               return (1);
-
-       /*
-        * Make child runnable and add to run queue.
-        */
-       (void) spl6();
-       rpp->p_stat = SRUN;
-       setrq(rpp);
-       (void) spl0();
-
-       /*
-        * Cause child to take a non-local goto as soon as it runs.
-        * On older systems this was done with SSWAP bit in proc
-        * table; on VAX we use u.u_pcb.pcb_sswap so don't need
-        * to do rpp->p_flag |= SSWAP.  Actually do nothing here.
-        */
-       /* rpp->p_flag |= SSWAP; */
-
-       /*
-        * Now can be swapped.
-        */
-       rip->p_flag &= ~SKEEP;
-
-       /*
-        * If vfork make chain from parent process to child
-        * (where virtal memory is temporarily).  Wait for
-        * child to finish, steal virtual memory back,
-        * and wakeup child to let it die.
-        */
-       if (isvfork) {
-               u.u_procp->p_xlink = rpp;
-               u.u_procp->p_flag |= SNOVM;
-               while (rpp->p_flag & SVFORK)
-                       sleep((caddr_t)rpp, PZERO - 1);
-               if ((rpp->p_flag & SLOAD) == 0)
-                       panic("newproc vfork");
-               uaccess(rpp, Vfmap, &vfutl);
-               u.u_procp->p_xlink = 0;
-               vpassvm(rpp, u.u_procp, &vfutl, &u, Vfmap);
-               u.u_procp->p_flag &= ~SNOVM;
-               rpp->p_ndx = rpp - proc;
-               rpp->p_flag |= SVFDONE;
-               wakeup((caddr_t)rpp);
-       }
-
-       /*
-        * 0 return means parent.
-        */
-       return (0);
-}
index 7972a77..822e1ab 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_prot.c     5.16    83/03/31        */
+/*     kern_prot.c     5.17    83/05/27        */
 
 /*
  * System calls related to processes and protection
 
 /*
  * System calls related to processes and protection
@@ -138,30 +138,6 @@ setreuid()
        u.u_uid = euid;
 }
 
        u.u_uid = euid;
 }
 
-#ifndef NOCOMPAT
-osetuid()
-{
-       register uid;
-       register struct a {
-               int     uid;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       uid = uap->uid;
-       if (u.u_ruid == uid || u.u_uid == uid || suser()) {
-#ifdef QUOTA
-               if (u.u_quota->q_uid != uid) {
-                       qclean();
-                       qstart(getquota(uid, 0, 0));
-               }
-#endif
-               u.u_uid = uid;
-               u.u_procp->p_uid = uid;
-               u.u_ruid = uid;
-       }
-}
-#endif
-
 setregid()
 {
        register struct a {
 setregid()
 {
        register struct a {
@@ -189,24 +165,6 @@ setregid()
        u.u_gid = egid;
 }
 
        u.u_gid = egid;
 }
 
-#ifndef NOCOMPAT
-osetgid()
-{
-       register gid;
-       register struct a {
-               int     gid;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       gid = uap->gid;
-       if (u.u_rgid == gid || u.u_gid == gid || suser()) {
-               leavegroup(u.u_rgid);
-               (void) entergroup(gid);
-               u.u_gid = gid;
-               u.u_rgid = gid;
-       }
-}
-
 setgroups()
 {
        register struct a {
 setgroups()
 {
        register struct a {
@@ -229,41 +187,6 @@ setgroups()
                *gp = NOGROUP;
 }
 
                *gp = NOGROUP;
 }
 
-/*
- * Pid of zero implies current process.
- * Pgrp -1 is getpgrp system call returning
- * current process group.
- */
-osetpgrp()
-{
-       register struct proc *p;
-       register struct a {
-               int     pid;
-               int     pgrp;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       if (uap->pid == 0)
-               p = u.u_procp;
-       else {
-               p = pfind(uap->pid);
-               if (p == 0) {
-                       u.u_error = ESRCH;
-                       return;
-               }
-       }
-       if (uap->pgrp <= 0) {
-               u.u_r.r_val1 = p->p_pgrp;
-               return;
-       }
-       if (p->p_uid != u.u_uid && u.u_uid && !inferior(p)) {
-               u.u_error = EPERM;
-               return;
-       }
-       p->p_pgrp = uap->pgrp;
-}
-/* END DEFUNCT */
-
 /*
  * Group utility functions.
  */
 /*
  * Group utility functions.
  */
index 9db1664..2adca5f 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_resource.c 4.21    83/05/23        */
+/*     kern_resource.c 4.22    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -236,86 +236,3 @@ ruadd(ru, ru2)
        for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
                *ip++ += *ip2++;
 }
        for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
                *ip++ += *ip2++;
 }
-
-#ifndef NOCOMPAT
-onice()
-{
-       register struct a {
-               int     niceness;
-       } *uap = (struct a *)u.u_ap;
-       register struct proc *p = u.u_procp;
-
-       donice(p, (p->p_nice-NZERO)+uap->niceness);
-}
-
-#include "../h/times.h"
-
-otimes()
-{
-       register struct a {
-               struct  tms *tmsb;
-       } *uap = (struct a *)u.u_ap;
-       struct tms atms;
-
-       atms.tms_utime = scale60(&u.u_ru.ru_utime);
-       atms.tms_stime = scale60(&u.u_ru.ru_stime);
-       atms.tms_cutime = scale60(&u.u_cru.ru_utime);
-       atms.tms_cstime = scale60(&u.u_cru.ru_stime);
-       u.u_error = copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms));
-}
-
-scale60(tvp)
-       register struct timeval *tvp;
-{
-
-       return (tvp->tv_sec * 60 + tvp->tv_usec / 16667);
-}
-
-#include "../h/vtimes.h"
-
-ovtimes()
-{
-       register struct a {
-               struct  vtimes *par;
-               struct  vtimes *chi;
-       } *uap = (struct a *)u.u_ap;
-       struct vtimes avt;
-
-       if (uap->par) {
-               getvtimes(&u.u_ru, &avt);
-               u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->par,
-                       sizeof (avt));
-               if (u.u_error)
-                       return;
-       }
-       if (uap->chi) {
-               getvtimes(&u.u_cru, &avt);
-               u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->chi,
-                       sizeof (avt));
-               if (u.u_error)
-                       return;
-       }
-}
-
-getvtimes(aru, avt)
-       register struct rusage *aru;
-       register struct vtimes *avt;
-{
-
-       avt->vm_utime = scale60(&aru->ru_utime);
-       avt->vm_stime = scale60(&aru->ru_stime);
-       avt->vm_idsrss = ((aru->ru_idrss+aru->ru_isrss) / hz) * 60;
-       avt->vm_ixrss = aru->ru_ixrss / hz * 60;
-       avt->vm_maxrss = aru->ru_maxrss;
-       avt->vm_majflt = aru->ru_majflt;
-       avt->vm_minflt = aru->ru_minflt;
-       avt->vm_nswap = aru->ru_nswap;
-       avt->vm_inblk = aru->ru_inblock;
-       avt->vm_oublk = aru->ru_oublock;
-}
-
-ovlimit()
-{
-
-       u.u_error = EACCES;
-}
index f3449c7..5639cc8 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_sig.c      5.16    83/05/21        */
+/*     kern_sig.c      5.17    83/05/27        */
 
 #include "../machine/reg.h"
 #include "../machine/pte.h"
 
 #include "../machine/reg.h"
 #include "../machine/pte.h"
@@ -57,7 +57,6 @@ kill()
 }
 #endif
 
 }
 #endif
 
-/* TEMPORARY */
 killpg()
 {
        register struct a {
 killpg()
 {
        register struct a {
@@ -65,22 +64,10 @@ killpg()
                int     signo;
        } *uap = (struct a *)u.u_ap;
 
                int     signo;
        } *uap = (struct a *)u.u_ap;
 
-       u.u_error = okill1(1, uap->signo, uap->pgrp);
+       u.u_error = kill1(1, uap->signo, uap->pgrp);
 }
 
 }
 
-/* BEGIN DEFUNCT */
-okill()
-{
-       register struct a {
-               int     pid;
-               int     signo;
-       } *uap = (struct a *)u.u_ap;
-
-       u.u_error = okill1(uap->signo < 0,
-               uap->signo < 0 ? -uap->signo : uap->signo, uap->pid);
-}
-
-okill1(ispgrp, signo, who)
+kill1(ispgrp, signo, who)
        int ispgrp, signo, who;
 {
        register struct proc *p;
        int ispgrp, signo, who;
 {
        register struct proc *p;
@@ -121,70 +108,7 @@ okill1(ispgrp, signo, who)
                f++;
                psignal(p, signo);
        }
                f++;
                psignal(p, signo);
        }
-       return (f == 0? ESRCH : 0);
-}
-
-ossig()
-{
-       register int (*f)();
-       struct a {
-               int     signo;
-               int     (*fun)();
-       } *uap;
-       register struct proc *p = u.u_procp;
-       register a;
-       long sigmask;
-
-       uap = (struct a *)u.u_ap;
-       a = uap->signo & SIGNUMMASK;
-       f = uap->fun;
-       if (a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP ||
-           a==SIGCONT && (f == SIG_IGN || f == SIG_HOLD)) {
-               u.u_error = EINVAL;
-               return;
-       }
-       if ((uap->signo &~ SIGNUMMASK) || (f != SIG_DFL && f != SIG_IGN &&
-           SIGISDEFER(f)))
-               u.u_procp->p_flag |= SNUSIG;
-       /* 
-        * Don't clobber registers if we are to simulate
-        * a ret+rti.
-        */
-       if ((uap->signo&SIGDORTI) == 0)
-               u.u_r.r_val1 = (int)u.u_signal[a];
-       /*
-        * Change setting atomically.
-        */
-       (void) spl6();
-       sigmask = 1L << (a-1);
-       if (f == SIG_IGN)
-               p->p_sig &= ~sigmask;           /* never to be seen again */
-       u.u_signal[a] = f;
-       if (f != SIG_DFL && f != SIG_IGN && f != SIG_HOLD)
-               f = SIG_CATCH;
-       if ((int)f & 1)
-               p->p_siga0 |= sigmask;
-       else
-               p->p_siga0 &= ~sigmask;
-       if ((int)f & 2)
-               p->p_siga1 |= sigmask;
-       else
-               p->p_siga1 &= ~sigmask;
-       (void) spl0();
-       /*
-        * Now handle options.
-        */
-       if (uap->signo & SIGDOPAUSE) {
-               /*
-                * Simulate a PDP11 style wait instrution which
-                * atomically lowers priority, enables interrupts
-                * and hangs.
-                */
-               opause();
-               /*NOTREACHED*/
-       }
-       if (uap->signo & SIGDORTI)
-               u.u_eosys = SIMULATERTI;
+       return (f == 0 ? ESRCH : 0);
 }
 
 /*
 }
 
 /*
@@ -617,14 +541,9 @@ psig()
                 */
                if (SIGISDEFER(action)) {
                        (void) spl6();
                 */
                if (SIGISDEFER(action)) {
                        (void) spl6();
-                       if ((int)SIG_HOLD & 1)
-                               rp->p_siga0 |= sigmask;
-                       else
-                               rp->p_siga0 &= ~sigmask;
-                       if ((int)SIG_HOLD & 2)
-                               rp->p_siga1 |= sigmask;
-                       else
-                               rp->p_siga1 &= ~sigmask;
+                       /* SIG_HOLD known to be 3 */
+                       rp->p_siga0 |= sigmask;
+                       rp->p_siga1 |= sigmask;
                        u.u_signal[n] = SIG_HOLD;
                        (void) spl0();
                        action = SIGUNDEFER(action);
                        u.u_signal[n] = SIG_HOLD;
                        (void) spl0();
                        action = SIGUNDEFER(action);
@@ -653,9 +572,6 @@ psig()
        exit(n);
 }
 
        exit(n);
 }
 
-#ifdef unneeded
-int    corestop = 0;
-#endif
 /*
  * Create a core image on the file "core"
  * If you are looking for protection glitches,
 /*
  * Create a core image on the file "core"
  * If you are looking for protection glitches,
@@ -671,17 +587,6 @@ core()
        register struct inode *ip;
        extern schar();
 
        register struct inode *ip;
        extern schar();
 
-#ifdef unneeded
-       if (corestop) {
-               int i;
-               for (i = 0; i < 10; i++)
-                       if (u.u_comm[i])
-                               putchar(u.u_comm[i], 0);
-               printf(", uid %d\n", u.u_uid);
-               if (corestop&2)
-                       asm("halt");
-       }
-#endif
        if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid)
                return (0);
        if (ctob(UPAGES+u.u_dsize+u.u_ssize) >=
        if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid)
                return (0);
        if (ctob(UPAGES+u.u_dsize+u.u_ssize) >=
index 28607a7..067821c 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_time.c     5.14    82/12/30        */
+/*     kern_time.c     5.15    83/05/27        */
 
 #include "../machine/reg.h"
 
 
 #include "../machine/reg.h"
 
@@ -298,73 +298,3 @@ timevalfix(t1)
                t1->tv_usec -= 1000000;
        }
 }
                t1->tv_usec -= 1000000;
        }
 }
-
-#ifndef NOCOMPAT
-otime()
-{
-
-       u.u_r.r_time = time.tv_sec;
-}
-
-ostime()
-{
-       register struct a {
-               int     time;
-       } *uap = (struct a *)u.u_ap;
-       struct timeval tv;
-
-       tv.tv_sec = uap->time;
-       tv.tv_usec = 0;
-       setthetime(&tv);
-}
-
-/* from old timeb.h */
-struct timeb {
-       time_t  time;
-       u_short millitm;
-       short   timezone;
-       short   dstflag;
-};
-
-oftime()
-{
-       register struct a {
-               struct  timeb   *tp;
-       } *uap;
-       struct timeb tb;
-
-       uap = (struct a *)u.u_ap;
-       (void) spl7();
-       tb.time = time.tv_sec;
-       tb.millitm = time.tv_usec / 1000;
-       (void) spl0();
-       tb.timezone = tz.tz_minuteswest;
-       tb.dstflag = tz.tz_dsttime;
-       u.u_error = copyout((caddr_t)&tb, (caddr_t)uap->tp, sizeof (tb));
-}
-
-oalarm()
-{
-       register struct a {
-               int     deltat;
-       } *uap = (struct a *)u.u_ap;
-       register struct proc *p = u.u_procp;
-       int s = spl7();
-
-       untimeout(realitexpire, (caddr_t)p);
-       timerclear(&p->p_realtimer.it_interval);
-       u.u_r.r_val1 = 0;
-       if (timerisset(&p->p_realtimer.it_value) &&
-           timercmp(&p->p_realtimer.it_value, &time, >))
-               u.u_r.r_val1 = p->p_realtimer.it_value.tv_sec - time.tv_sec;
-       if (uap->deltat == 0) {
-               timerclear(&p->p_realtimer.it_value);
-               splx(s);
-               return;
-       }
-       p->p_realtimer.it_value = time;
-       p->p_realtimer.it_value.tv_sec += uap->deltat;
-       timeout(realitexpire, (caddr_t)p, hzto(&p->p_realtimer.it_value));
-       splx(s);
-}
-#endif
index 7519623..ac4f2b3 100644 (file)
@@ -1,4 +1,4 @@
-/*     subr_prf.c      4.26    83/05/18        */
+/*     subr_prf.c      4.27    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -202,6 +202,7 @@ tablefull(tab)
        printf("%s: table is full\n", tab);
 }
 
        printf("%s: table is full\n", tab);
 }
 
+#ifdef vax
 /*
  * Hard error is the preface to plaintive error messages
  * about failing disk transfers.
 /*
  * Hard error is the preface to plaintive error messages
  * about failing disk transfers.
@@ -214,6 +215,7 @@ harderr(bp, cp)
        printf("%s%d%c: hard error sn%d ", cp,
            dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
 }
        printf("%s%d%c: hard error sn%d ", cp,
            dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
 }
+#endif
 
 /*
  * Print a character on console or users terminal.
 
 /*
  * Print a character on console or users terminal.
index 86efb60..7137d22 100644 (file)
@@ -1,4 +1,4 @@
-/*     subr_xxx.c      4.21    82/12/17        */
+/*     subr_xxx.c      4.22    83/05/27        */
 
 #include "../machine/pte.h"
 
 
 #include "../machine/pte.h"
 
@@ -103,7 +103,7 @@ ffs(mask)
 {
        register int i;
 
 {
        register int i;
 
-       for(i=1; i<NSIG; i++) {
+       for(i = 1; i < NSIG; i++) {
                if (mask & 1)
                        return (i);
                mask >>= 1;
                if (mask & 1)
                        return (i);
                mask >>= 1;
index f051d7e..56ff7b8 100644 (file)
@@ -1,22 +1,15 @@
-/*     sys_generic.c   5.35    83/05/21        */
+/*     sys_generic.c   5.36    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/ioctl.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/ioctl.h"
-#include "../h/tty.h"
 #include "../h/file.h"
 #include "../h/file.h"
-#include "../h/inode.h"
-#include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/proc.h"
-#include "../h/conf.h"
-#include "../h/socket.h"
-#include "../h/socketvar.h"
-#include "../h/fs.h"
-#include "../h/descrip.h"
 #include "../h/uio.h"
 #include "../h/uio.h"
-#include "../h/cmap.h"
+#include "../h/kernel.h"
+#include "../h/stat.h"
 
 /*
  * Read system call.
 
 /*
  * Read system call.
@@ -113,7 +106,6 @@ rwuio(uio, rw)
        };
        register struct file *fp;
        register struct iovec *iov;
        };
        register struct file *fp;
        register struct iovec *iov;
-       register struct inode *ip;
        int i, count;
 
        GETF(fp, ((struct a *)u.u_ap)->fdes);
        int i, count;
 
        GETF(fp, ((struct a *)u.u_ap)->fdes);
@@ -136,318 +128,18 @@ rwuio(uio, rw)
                }
        }
        count = uio->uio_resid;
                }
        }
        count = uio->uio_resid;
+       uio->uio_offset = fp->f_offset;
        if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) {
                if (uio->uio_resid == count)
                        u.u_eosys = RESTARTSYS;
        if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) {
                if (uio->uio_resid == count)
                        u.u_eosys = RESTARTSYS;
-       } else if (fp->f_type == DTYPE_SOCKET) {
-               int sosend(), soreceive();
-               u.u_error = 
-                   (*(rw==UIO_READ?soreceive:sosend))
-                     (fp->f_socket, (struct sockaddr *)0, uio, 0);
-       } else {
-               ip = fp->f_inode;
-               uio->uio_offset = fp->f_offset;
-               if ((ip->i_mode&IFMT) == IFREG) {
-                       ILOCK(ip);
-                       if (fp->f_flag&FAPPEND && rw == UIO_WRITE)
-                               uio->uio_offset = fp->f_offset = ip->i_size;
-                       u.u_error = rwip(ip, uio, rw);
-                       IUNLOCK(ip);
-               } else
-                       u.u_error = rwip(ip, uio, rw);
-               fp->f_offset += count - uio->uio_resid;
-       }
-       u.u_r.r_val1 = count - uio->uio_resid;
-}
-
-rdwri(rw, ip, base, len, offset, segflg, aresid)
-       struct inode *ip;
-       caddr_t base;
-       int len, offset, segflg;
-       int *aresid;
-       enum uio_rw rw;
-{
-       struct uio auio;
-       struct iovec aiov;
-       int error;
-
-       auio.uio_iov = &aiov;
-       auio.uio_iovcnt = 1;
-       aiov.iov_base = base;
-       aiov.iov_len = len;
-       auio.uio_resid = len;
-       auio.uio_offset = offset;
-       auio.uio_segflg = segflg;
-       error = rwip(ip, &auio, rw);
-       if (aresid)
-               *aresid = auio.uio_resid;
-       else
-               if (auio.uio_resid)
-                       error = EIO;
-       return (error);
-}
-
-rwip(ip, uio, rw)
-       register struct inode *ip;
-       register struct uio *uio;
-       enum uio_rw rw;
-{
-       dev_t dev = (dev_t)ip->i_rdev;
-       struct buf *bp;
-       struct fs *fs;
-       daddr_t lbn, bn;
-       register int n, on, type;
-       int size;
-       long bsize;
-       extern int mem_no;
-       int error = 0;
-
-       if (rw != UIO_READ && rw != UIO_WRITE)
-               panic("rwip");
-       if (rw == UIO_READ && uio->uio_resid == 0)
-               return (0);
-       if (uio->uio_offset < 0 &&
-           ((ip->i_mode&IFMT) != IFCHR || mem_no != major(dev)))
-               return (EINVAL);
-       if (rw == UIO_READ)
-               ip->i_flag |= IACC;
-       type = ip->i_mode&IFMT;
-       if (type == IFCHR) {
-               if (rw == UIO_READ)
-                       u.u_error = (*cdevsw[major(dev)].d_read)(dev, uio);
-               else {
-                       ip->i_flag |= IUPD|ICHG;
-                       u.u_error = (*cdevsw[major(dev)].d_write)(dev, uio);
-               }
-               return (u.u_error);
-       }
-       if (uio->uio_resid == 0)
-               return (0);
-       if (rw == UIO_WRITE && type == IFREG &&
-           uio->uio_offset + uio->uio_resid >
-             u.u_rlimit[RLIMIT_FSIZE].rlim_cur) {
-               psignal(u.u_procp, SIGXFSZ);
-               return (EMFILE);
-       }
-       if (type != IFBLK) {
-               dev = ip->i_dev;
-               fs = ip->i_fs;
-               bsize = fs->fs_bsize;
        } else
        } else
-               bsize = BLKDEV_IOSIZE;
-       do {
-               lbn = uio->uio_offset / bsize;
-               on = uio->uio_offset % bsize;
-               n = MIN((unsigned)(bsize - on), uio->uio_resid);
-               if (type != IFBLK) {
-                       if (rw == UIO_READ) {
-                               int diff = ip->i_size - uio->uio_offset;
-                               if (diff <= 0)
-                                       return (0);
-                               if (diff < n)
-                                       n = diff;
-                       }
-                       bn = fsbtodb(fs,
-                           bmap(ip, lbn, rw == UIO_WRITE ? B_WRITE: B_READ, (int)(on+n)));
-                       if (u.u_error || rw == UIO_WRITE && (long)bn<0)
-                               return (u.u_error);
-                       if (rw == UIO_WRITE && uio->uio_offset + n > ip->i_size &&
-                          (type == IFDIR || type == IFREG || type == IFLNK))
-                               ip->i_size = uio->uio_offset + n;
-                       size = blksize(fs, ip, lbn);
-               } else {
-                       bn = lbn * (BLKDEV_IOSIZE/DEV_BSIZE);
-                       rablock = bn + (BLKDEV_IOSIZE/DEV_BSIZE);
-                       rasize = size = bsize;
-               }
-               if (rw == UIO_READ) {
-                       if ((long)bn<0) {
-                               bp = geteblk(size);
-                               clrbuf(bp);
-                       } else if (ip->i_lastr + 1 == lbn)
-                               bp = breada(dev, bn, size, rablock, rasize);
-                       else
-                               bp = bread(dev, bn, size);
-                       ip->i_lastr = lbn;
-               } else {
-                       int i, count;
-                       extern struct cmap *mfind();
-
-                       count = howmany(size, DEV_BSIZE);
-                       for (i = 0; i < count; i += CLSIZE)
-                               if (mfind(dev, bn + i))
-                                       munhash(dev, bn + i);
-                       if (n == bsize) 
-                               bp = getblk(dev, bn, size);
-                       else
-                               bp = bread(dev, bn, size);
-               }
-               n = MIN(n, size - bp->b_resid);
-               if (bp->b_flags & B_ERROR) {
-                       error = EIO;
-                       brelse(bp);
-                       goto bad;
-               }
-               u.u_error =
-                   uiomove(bp->b_un.b_addr+on, n, rw, uio);
-               if (rw == UIO_READ) {
-                       if (n + on == bsize || uio->uio_offset == ip->i_size)
-                               bp->b_flags |= B_AGE;
-                       brelse(bp);
-               } else {
-                       if ((ip->i_mode&IFMT) == IFDIR)
-                               bwrite(bp);
-                       else if (n + on == bsize) {
-                               bp->b_flags |= B_AGE;
-                               bawrite(bp);
-                       } else
-                               bdwrite(bp);
-                       ip->i_flag |= IUPD|ICHG;
-                       if (u.u_ruid != 0)
-                               ip->i_mode &= ~(ISUID|ISGID);
-               }
-       } while (u.u_error == 0 && uio->uio_resid > 0 && n != 0);
-bad:
-       return (error);
-}
-
-uiomove(cp, n, rw, uio)
-       register caddr_t cp;
-       register int n;
-       enum uio_rw rw;
-       register struct uio *uio;
-{
-       register struct iovec *iov;
-       u_int cnt;
-       int error = 0;
-
-       while (n > 0 && uio->uio_resid) {
-               iov = uio->uio_iov;
-               cnt = iov->iov_len;
-               if (cnt == 0) {
-                       uio->uio_iov++;
-                       uio->uio_iovcnt--;
-                       continue;
-               }
-               if (cnt > n)
-                       cnt = n;
-               switch (uio->uio_segflg) {
-
-               case 0:
-               case 2:
-                       if (rw == UIO_READ)
-                               error = copyout(cp, iov->iov_base, cnt);
-                       else
-                               error = copyin(iov->iov_base, cp, cnt);
-                       if (error)
-                               return (error);
-                       break;
-
-               case 1:
-                       if (rw == UIO_READ)
-                               bcopy((caddr_t)cp, iov->iov_base, cnt);
-                       else
-                               bcopy(iov->iov_base, (caddr_t)cp, cnt);
-                       break;
-               }
-               iov->iov_base += cnt;
-               iov->iov_len -= cnt;
-               uio->uio_resid -= cnt;
-               uio->uio_offset += cnt;
-               cp += cnt;
-               n -= cnt;
-       }
-       return (error);
-}
-
-/*
- * Give next character to user as result of read.
- */
-ureadc(c, uio)
-       register int c;
-       register struct uio *uio;
-{
-       register struct iovec *iov;
-
-again:
-       if (uio->uio_iovcnt == 0)
-               panic("ureadc");
-       iov = uio->uio_iov;
-       if (iov->iov_len <= 0 || uio->uio_resid <= 0) {
-               uio->uio_iovcnt--;
-               uio->uio_iov++;
-               goto again;
-       }
-       switch (uio->uio_segflg) {
-
-       case 0:
-               if (subyte(iov->iov_base, c) < 0)
-                       return (EFAULT);
-               break;
-
-       case 1:
-               *iov->iov_base = c;
-               break;
-
-       case 2:
-               if (suibyte(iov->iov_base, c) < 0)
-                       return (EFAULT);
-               break;
-       }
-       iov->iov_base++;
-       iov->iov_len--;
-       uio->uio_resid--;
-       uio->uio_offset++;
-       return (0);
-}
-
-#ifdef notdef
-/*
- * Get next character written in by user from uio.
- */
-uwritec(uio)
-       struct uio *uio;
-{
-       register struct iovec *iov;
-       register int c;
-
-again:
-       if (uio->uio_iovcnt <= 0 || uio->uio_resid <= 0)
-               panic("uwritec");
-       iov = uio->uio_iov;
-       if (iov->iov_len == 0) {
-               uio->uio_iovcnt--;
-               uio->uio_iov++;
-               goto again;
-       }
-       switch (uio->uio_segflg) {
-
-       case 0:
-               c = fubyte(iov->iov_base);
-               break;
-
-       case 1:
-               c = *iov->iov_base & 0377;
-               break;
-
-       case 2:
-               c = fuibyte(iov->iov_base);
-               break;
-       }
-       if (c < 0)
-               return (-1);
-       iov->iov_base++;
-       iov->iov_len--;
-       uio->uio_resid--;
-       uio->uio_offset++;
-       return (c & 0377);
+               u.u_error = (*fp->f_ops->fo_rw)(fp, rw, uio);
+       u.u_r.r_val1 = count - uio->uio_resid;
+       fp->f_offset += u.u_r.r_val1;
 }
 }
-#endif
 
 /*
  * Ioctl system call
 
 /*
  * Ioctl system call
- * Check legality, execute common code,
- * and switch out to individual device routine.
  */
 ioctl()
 {
  */
 ioctl()
 {
@@ -470,7 +162,7 @@ ioctl()
        }
        com = uap->cmd;
 
        }
        com = uap->cmd;
 
-#ifndef NOCOMPAT
+#if defined(vax) && !defined(NOCOMPAT)
        /*
         * Map old style ioctl's into new for the
         * sake of backwards compatibility (sigh).
        /*
         * Map old style ioctl's into new for the
         * sake of backwards compatibility (sigh).
@@ -519,33 +211,25 @@ ioctl()
        else if (com&IOC_VOID)
                *(caddr_t *)data = uap->cmarg;
 
        else if (com&IOC_VOID)
                *(caddr_t *)data = uap->cmarg;
 
-       if (fp->f_type == DTYPE_SOCKET)
-               u.u_error = soioctl(fp->f_socket, com, data);
-       else {
-               register struct inode *ip = fp->f_inode;
-               int fmt = ip->i_mode & IFMT;
-               dev_t dev;
-
-               if (fmt != IFCHR) {
-                       if (com == FIONREAD && (fmt == IFREG || fmt == IFDIR)) {
-                               *(off_t *)data = ip->i_size - fp->f_offset;
-                               goto returndata;
-                       }
-                       if (com != FIONBIO && com != FIOASYNC)
-                               u.u_error = ENOTTY;
-                       return;
-               }
-               dev = ip->i_rdev;
-               u.u_r.r_val1 = 0;
-               if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) {
-                       u.u_eosys = RESTARTSYS;
-                       return;
-               }
-               u.u_error =
-                  (*cdevsw[major(dev)].d_ioctl)(dev, com, data, fp->f_flag);
-       }
+       switch (com) {
+
+       case FIONBIO:
+               u.u_error = fset(fp, FNDELAY, *(int *)data);
+               return;
+
+       case FIOASYNC:
+               u.u_error = fset(fp, FASYNC, *(int *)data);
+               return;
+
+       case FIOSETOWN:
+               u.u_error = fsetown(fp, *(int *)data);
+               return;
 
 
-returndata:
+       case FIOGETOWN:
+               u.u_error = fgetown(fp, (int *)data);
+               return;
+       }
+       u.u_error = (*fp->f_ops->fo_ioctl)(fp, com, data);
        /*
         * Copy any data to user, size was
         * already set and checked above.
        /*
         * Copy any data to user, size was
         * already set and checked above.
@@ -554,29 +238,197 @@ returndata:
                u.u_error = copyout(data, uap->cmarg, (u_int)size);
 }
 
                u.u_error = copyout(data, uap->cmarg, (u_int)size);
 }
 
+int    unselect();
+int    nselcoll;
 /*
 /*
- * Do nothing specific version of line
- * discipline specific ioctl command.
+ * Select system call.
  */
  */
+select()
+{
+       register struct uap  {
+               int     nd;
+               long    *in, *ou, *ex;
+               struct  timeval *tv;
+       } *uap = (struct uap *)u.u_ap;
+       int ibits[3], obits[3];
+       struct timeval atv;
+       int s, ncoll;
+       label_t lqsave;
+
+       obits[0] = obits[1] = obits[2] = 0;
+       if (uap->nd > NOFILE)
+               uap->nd = NOFILE;       /* forgiving, if slightly wrong */
+
+#define        getbits(name, x) \
+       if (uap->name) { \
+               u.u_error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \
+                   sizeof (ibits[x])); \
+               if (u.u_error) \
+                       goto done; \
+       } else \
+               ibits[x] = 0;
+       getbits(in, 0);
+       getbits(ou, 1);
+       getbits(ex, 2);
+#undef getbits
+
+       if (uap->tv) {
+               u.u_error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
+                       sizeof (atv));
+               if (u.u_error)
+                       goto done;
+               if (itimerfix(&atv)) {
+                       u.u_error = EINVAL;
+                       goto done;
+               }
+               s = spl7(); timevaladd(&atv, &time); splx(s);
+       }
+retry:
+       ncoll = nselcoll;
+       u.u_procp->p_flag |= SSEL;
+       u.u_r.r_val1 = selscan(ibits, obits);
+       if (u.u_error || u.u_r.r_val1)
+               goto done;
+       s = spl6();
+       if (uap->tv && timercmp(&time, &atv, >=)) {
+               splx(s);
+               goto done;
+       }
+       if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) {
+               u.u_procp->p_flag &= ~SSEL;
+               splx(s);
+               goto retry;
+       }
+       u.u_procp->p_flag &= ~SSEL;
+       if (uap->tv) {
+               lqsave = u.u_qsave;
+               if (setjmp(&u.u_qsave)) {
+                       untimeout(unselect, (caddr_t)u.u_procp);
+                       u.u_error = EINTR;
+                       splx(s);
+                       goto done;
+               }
+               timeout(unselect, (caddr_t)u.u_procp, hzto(&atv));
+       }
+       sleep((caddr_t)&selwait, PZERO+1);
+       if (uap->tv) {
+               u.u_qsave = lqsave;
+               untimeout(unselect, (caddr_t)u.u_procp);
+       }
+       splx(s);
+       goto retry;
+done:
+#define        putbits(name, x) \
+       if (uap->name) { \
+               int error = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \
+                   sizeof (obits[x])); \
+               if (error) \
+                       u.u_error = error; \
+       }
+       putbits(in, 0);
+       putbits(ou, 1);
+       putbits(ex, 2);
+#undef putbits
+}
+
+unselect(p)
+       register struct proc *p;
+{
+       register int s = spl6();
+
+       switch (p->p_stat) {
+
+       case SSLEEP:
+               setrun(p);
+               break;
+
+       case SSTOP:
+               unsleep(p);
+               break;
+       }
+       splx(s);
+}
+
+selscan(ibits, obits)
+       int *ibits, *obits;
+{
+       register int which, bits, i;
+       int flag;
+       struct file *fp;
+       int n = 0;
+
+       for (which = 0; which < 3; which++) {
+               bits = ibits[which];
+               obits[which] = 0;
+               switch (which) {
+
+               case 0:
+                       flag = FREAD; break;
+
+               case 1:
+                       flag = FWRITE; break;
+
+               case 2:
+                       flag = 0; break;
+               }
+               while (i = ffs(bits)) {
+                       bits &= ~(1<<(i-1));
+                       fp = u.u_ofile[i-1];
+                       if (fp == NULL) {
+                               u.u_error = EBADF;
+                               break;
+                       }
+                       if ((*fp->f_ops->fo_select)(fp, flag)) {
+                               obits[which] |= (1<<(i-1));
+                               n++;
+                       }
+               }
+       }
+       return (n);
+}
+
 /*ARGSUSED*/
 /*ARGSUSED*/
-nullioctl(tp, cmd, data, flags)
-       struct tty *tp;
-       char *data;
-       int flags;
+seltrue(dev, flag)
+       dev_t dev;
+       int flag;
 {
 
 {
 
-#ifdef lint
-       tp = tp; data = data; flags = flags;
-#endif
-       return (-1);
+       return (1);
 }
 
 }
 
-ostty()
+selwakeup(p, coll)
+       register struct proc *p;
+       int coll;
 {
 
 {
 
+       if (coll) {
+               nselcoll++;
+               wakeup((caddr_t)&selwait);
+       }
+       if (p) {
+               int s = spl6();
+               if (p->p_wchan == (caddr_t)&selwait)
+                       setrun(p);
+               else if (p->p_flag & SSEL)
+                       p->p_flag &= ~SSEL;
+               splx(s);
+       }
 }
 
 }
 
-ogtty()
+fstat()
 {
 {
+       register struct file *fp;
+       register struct a {
+               int     fdes;
+               struct  stat *sb;
+       } *uap;
+       struct stat ub;
 
 
+       uap = (struct a *)u.u_ap;
+       fp = getf(uap->fdes);
+       if (fp == 0)
+               return;
+       u.u_error = (*fp->f_ops->fo_stat)(fp, &ub);
+       if (u.u_error == 0)
+               u.u_error = copyout(&ub, uap->sb, sizeof (ub));
 }
 }
index 9b6d093..c2f74f3 100644 (file)
@@ -1,4 +1,4 @@
-/*     tty.c   4.40    83/02/10        */
+/*     tty.c   4.41    83/05/27        */
 
 #include "../machine/reg.h"
 
 
 #include "../machine/reg.h"
 
@@ -112,26 +112,32 @@ ttychars(tp)
 /*
  * Wait for output to drain, then flush input waiting.
  */
 /*
  * Wait for output to drain, then flush input waiting.
  */
-wflushtty(tp)
+ttywflush(tp)
        register struct tty *tp;
 {
        register struct tty *tp;
 {
-       int s;
 
 
-       s = spl5();
+       ttywait(tp);
+       ttyflush(tp, FREAD);
+}
+
+ttywait(tp)
+       register struct tty *tp;
+{
+       register int s = spl5();
+
        while (tp->t_outq.c_cc && tp->t_state&TS_CARR_ON
            && tp->t_oproc) {           /* kludge for pty */
                (*tp->t_oproc)(tp);
                tp->t_state |= TS_ASLEEP;
                sleep((caddr_t)&tp->t_outq, TTOPRI);
        }
        while (tp->t_outq.c_cc && tp->t_state&TS_CARR_ON
            && tp->t_oproc) {           /* kludge for pty */
                (*tp->t_oproc)(tp);
                tp->t_state |= TS_ASLEEP;
                sleep((caddr_t)&tp->t_outq, TTOPRI);
        }
-       flushtty(tp, FREAD);
        splx(s);
 }
 
 /*
  * Flush all TTY queues
  */
        splx(s);
 }
 
 /*
  * Flush all TTY queues
  */
-flushtty(tp, rw)
+ttyflush(tp, rw)
        register struct tty *tp;
 {
        register s;
        register struct tty *tp;
 {
        register s;
@@ -170,7 +176,7 @@ ttyblock(tp)
 
        x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
        if (tp->t_rawq.c_cc > TTYHOG) {
 
        x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
        if (tp->t_rawq.c_cc > TTYHOG) {
-               flushtty(tp, FREAD|FWRITE);
+               ttyflush(tp, FREAD|FWRITE);
                tp->t_state &= ~TS_TBLOCK;
        }
        if (x >= TTYHOG/2 && putc(tp->t_stopc, &tp->t_outq) == 0) {
                tp->t_state &= ~TS_TBLOCK;
        }
        if (x >= TTYHOG/2 && putc(tp->t_stopc, &tp->t_outq) == 0) {
@@ -224,6 +230,7 @@ ttioctl(tp, com, data, flag)
        int dev = tp->t_dev;
        extern int nldisp;
        int s;
        int dev = tp->t_dev;
        extern int nldisp;
        int s;
+       register int newflags;
 
        /*
         * If the ioctl involves modification,
 
        /*
         * If the ioctl involves modification,
@@ -300,64 +307,9 @@ ttioctl(tp, com, data, flag)
                tp->t_state &= ~TS_XCLUDE;
                break;
 
                tp->t_state &= ~TS_XCLUDE;
                break;
 
-       case TIOCSET:
-       case TIOCBIS: {
-               u_long newflags = *(u_long *)data;
-
-               s = spl5();
-               if (tp->t_flags&RAW || newflags&RAW)
-                       wflushtty(tp);
-               else if ((tp->t_flags&CBREAK) != (newflags&CBREAK))
-                       if (newflags&CBREAK) {
-                               struct clist tq;
-
-                               catq(&tp->t_rawq, &tp->t_canq);
-                               tq = tp->t_rawq;
-                               tp->t_rawq = tp->t_canq;
-                               tp->t_canq = tq;
-                       } else {
-                               tp->t_flags |= PENDIN;
-                               ttwakeup(tp);
-                       }
-               if (com == TIOCSET)
-                       tp->t_flags = newflags;
-               else
-                       tp->t_flags |= newflags;
-               if (tp->t_flags&RAW) {
-                       tp->t_state &= ~TS_TTSTOP;
-                       ttstart(tp);
-               }
-               splx(s);
-               break;
-       }
-
-       case TIOCBIC: {
-               u_long newflags = *(long *)data;
-
-               if (tp->t_flags&RAW)
-                       wflushtty(tp);
-               else if ((tp->t_flags&CBREAK) != (CBREAK&~newflags))
-                       if (newflags&CBREAK) {
-                               tp->t_flags |= PENDIN;
-                               ttwakeup(tp);
-                       } else {
-                               struct clist tq;
-
-                               catq(&tp->t_rawq, &tp->t_canq);
-                               tq = tp->t_rawq;
-                               tp->t_rawq = tp->t_canq;
-                               tp->t_canq = tq;
-                       }
-               if (tp->t_flags&RAW) {
-                       tp->t_state &= ~TS_TTSTOP;
-                       ttstart(tp);
-               }
-               splx(s);
-               break;
-       }
 
        case TIOCGET:
 
        case TIOCGET:
-               *(long *)data = tp->t_flags;
+               *(int *)data = tp->t_flags;
                break;
 
        case TIOCCGET:
                break;
 
        case TIOCCGET:
@@ -380,7 +332,7 @@ ttioctl(tp, com, data, flag)
                        flags = FREAD|FWRITE;
                else
                        flags &= FREAD|FWRITE;
                        flags = FREAD|FWRITE;
                else
                        flags &= FREAD|FWRITE;
-               flushtty(tp, flags);
+               ttyflush(tp, flags);
                break;
        }
 
                break;
        }
 
@@ -417,12 +369,118 @@ ttioctl(tp, com, data, flag)
                (*linesw[tp->t_line].l_rint)(*(char *)data, tp);
                break;
 
                (*linesw[tp->t_line].l_rint)(*(char *)data, tp);
                break;
 
+       case TIOCSET:
+       case TIOCBIS:
+       case TIOCBIC:
+               newflags = *(int *)data;
+               if (com == TIOCBIS)
+                       newflags |= tp->t_flags;
+               else if (com == TIOCBIC)
+                       newflags = tp->t_flags &~ newflags;
+               goto setin;
+
+       case TIOCSETP:
+       case TIOCSETN: {
+               register struct sgttyb *sg = (struct sgttyb *)data;
+
+               tp->t_erase = sg->sg_erase;
+               tp->t_kill = sg->sg_kill;
+               tp->t_ispeed = sg->sg_ispeed;
+               tp->t_ospeed = sg->sg_ospeed;
+               newflags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff);
+setin:
+               s = spl5();
+               if (tp->t_flags&RAW || newflags&RAW || com == TIOCSETP) {
+                       ttywait(tp);
+                       ttyflush(tp, FREAD);
+               } else if ((tp->t_flags&CBREAK) != (newflags&CBREAK)) {
+                       if (newflags&CBREAK) {
+                               struct clist tq;
+
+                               catq(&tp->t_rawq, &tp->t_canq);
+                               tq = tp->t_rawq;
+                               tp->t_rawq = tp->t_canq;
+                               tp->t_canq = tq;
+                       } else {
+                               tp->t_flags |= PENDIN;
+                               ttwakeup(tp);
+                       }
+               }
+               tp->t_flags = newflags;
+               if (tp->t_flags&RAW) {
+                       tp->t_state &= ~TS_TTSTOP;
+                       ttstart(tp);
+               }
+               splx(s);
+               break;
+       }
+
+       /* send current parameters to user */
+       case TIOCGETP: {
+               register struct sgttyb *sg = (struct sgttyb *)data;
+
+               sg->sg_ispeed = tp->t_ispeed;
+               sg->sg_ospeed = tp->t_ospeed;
+               sg->sg_erase = tp->t_erase;
+               sg->sg_kill = tp->t_kill;
+               sg->sg_flags = tp->t_flags;
+               break;
+       }
+
+       case FIONBIO:
+               if (*(int *)data)
+                       tp->t_state |= TS_NBIO;
+               else
+                       tp->t_state &= ~TS_NBIO;
+               break;
+
+       case FIOASYNC:
+               if (*(int *)data)
+                       tp->t_state |= TS_ASYNC;
+               else
+                       tp->t_state &= ~TS_ASYNC;
+               break;
+
+       /* set/get local special characters */
+       case TIOCSLTC:
+               bcopy(data, (caddr_t)&tp->t_suspc, sizeof (struct ltchars));
+               break;
+
+       case TIOCGLTC:
+               bcopy((caddr_t)&tp->t_suspc, data, sizeof (struct ltchars));
+               break;
+
+       /*
+        * Modify local mode word.
+        */
+       case TIOCLBIS:
+               tp->t_flags |= *(int *)data << 16;
+               break;
+
+       case TIOCLBIC:
+               tp->t_flags &= ~(*(int *)data << 16);
+               break;
+
+       case TIOCLSET:
+               tp->t_flags &= 0xffff;
+               tp->t_flags |= *(int *)data << 16;
+               break;
+
+       case TIOCLGET:
+               *(int *)data = tp->t_flags >> 16;
+               break;
+
+       /* should allow SPGRP and GPGRP only if tty open for reading */
+       case TIOCSPGRP:
+               tp->t_pgrp = *(int *)data;
+               break;
+
+       case TIOCGPGRP:
+               *(int *)data = tp->t_pgrp;
+               break;
+
        default:
        default:
-#ifndef NOCOMPAT
-               return (ottioctl(tp, com, data, flag));
-#else
                return (-1);
                return (-1);
-#endif
        }
        return (0);
 }
        }
        return (0);
 }
@@ -498,7 +556,7 @@ ttyopen(dev, tp)
        tp->t_state &= ~TS_WOPEN;
        tp->t_state |= TS_ISOPEN;
        if (tp->t_line != NTTYDISC)
        tp->t_state &= ~TS_WOPEN;
        tp->t_state |= TS_ISOPEN;
        if (tp->t_line != NTTYDISC)
-               wflushtty(tp);
+               ttywflush(tp);
        return (0);
 }
 
        return (0);
 }
 
@@ -510,12 +568,12 @@ ttyclose(tp)
 {
 
        if (tp->t_line) {
 {
 
        if (tp->t_line) {
-               wflushtty(tp);
+               ttywflush(tp);
                tp->t_line = 0;
                return;
        }
        tp->t_pgrp = 0;
                tp->t_line = 0;
                return;
        }
        tp->t_pgrp = 0;
-       wflushtty(tp);
+       ttywflush(tp);
        tp->t_state = 0;
 }
 
        tp->t_state = 0;
 }
 
@@ -573,7 +631,7 @@ ttyinput(c, tp)
                 * in input q w/o interpretation.
                 */
                if (tp->t_rawq.c_cc > TTYHOG) 
                 * in input q w/o interpretation.
                 */
                if (tp->t_rawq.c_cc > TTYHOG) 
-                       flushtty(tp, FREAD|FWRITE);
+                       ttyflush(tp, FREAD|FWRITE);
                else {
                        if (putc(c, &tp->t_rawq) >= 0)
                                ttwakeup(tp);
                else {
                        if (putc(c, &tp->t_rawq) >= 0)
                                ttwakeup(tp);
@@ -614,7 +672,7 @@ ttyinput(c, tp)
                        if (tp->t_flags&FLUSHO)
                                tp->t_flags &= ~FLUSHO;
                        else {
                        if (tp->t_flags&FLUSHO)
                                tp->t_flags &= ~FLUSHO;
                        else {
-                               flushtty(tp, FWRITE);
+                               ttyflush(tp, FWRITE);
                                ttyecho(c, tp);
                                if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
                                        ttyretype(tp);
                                ttyecho(c, tp);
                                if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
                                        ttyretype(tp);
@@ -624,7 +682,7 @@ ttyinput(c, tp)
                }
                if (c == tp->t_suspc) {
                        if ((tp->t_flags&NOFLSH) == 0)
                }
                if (c == tp->t_suspc) {
                        if ((tp->t_flags&NOFLSH) == 0)
-                               flushtty(tp, FREAD);
+                               ttyflush(tp, FREAD);
                        ttyecho(c, tp);
                        gsignal(tp->t_pgrp, SIGTSTP);
                        goto endcase;
                        ttyecho(c, tp);
                        gsignal(tp->t_pgrp, SIGTSTP);
                        goto endcase;
@@ -652,7 +710,7 @@ ttyinput(c, tp)
         */
        if (c == tp->t_intrc || c == tp->t_quitc) {
                if ((tp->t_flags&NOFLSH) == 0)
         */
        if (c == tp->t_intrc || c == tp->t_quitc) {
                if ((tp->t_flags&NOFLSH) == 0)
-                       flushtty(tp, FREAD|FWRITE);
+                       ttyflush(tp, FREAD|FWRITE);
                ttyecho(c, tp);
                gsignal(tp->t_pgrp, c == tp->t_intrc ? SIGINT : SIGQUIT);
                goto endcase;
                ttyecho(c, tp);
                gsignal(tp->t_pgrp, c == tp->t_intrc ? SIGINT : SIGQUIT);
                goto endcase;
@@ -898,7 +956,7 @@ ttyoutput(c, tp)
        case NEWLINE:
                ctype = (tp->t_flags >> 8) & 03;
                if (ctype == 1) { /* tty 37 */
        case NEWLINE:
                ctype = (tp->t_flags >> 8) & 03;
                if (ctype == 1) { /* tty 37 */
-                       if (*colp)
+                       if (*colp > 0)
                                c = max(((unsigned)*colp>>4) + 3, (unsigned)6);
                } else if (ctype == 2) /* vt05 */
                        c = 6;
                                c = max(((unsigned)*colp>>4) + 3, (unsigned)6);
                } else if (ctype == 2) /* vt05 */
                        c = 6;
@@ -1153,7 +1211,7 @@ loop:
                if (cc > OBUFSIZ)
                        cc = OBUFSIZ;
                cp = obuf;
                if (cc > OBUFSIZ)
                        cc = OBUFSIZ;
                cp = obuf;
-               error = uiomove(cp, (unsigned)cc, UIO_WRITE, uio);
+               error = uiomove(cp, cc, UIO_WRITE, uio);
                if (error)
                        break;
                if (tp->t_outq.c_cc > hiwat)
                if (error)
                        break;
                if (tp->t_outq.c_cc > hiwat)
@@ -1194,7 +1252,8 @@ loop:
                        if (tp->t_flags & (RAW|LITOUT))
                                ce = cc;
                        else {
                        if (tp->t_flags & (RAW|LITOUT))
                                ce = cc;
                        else {
-                               ce = cc - scanc(cc, cp, partab, 077);
+                               ce = cc - scanc((unsigned)cc, (caddr_t)cp,
+                                  (caddr_t)partab, 077);
                                /*
                                 * If ce is zero, then we're processing
                                 * a special character through ttyoutput.
                                /*
                                 * If ce is zero, then we're processing
                                 * a special character through ttyoutput.
@@ -1460,6 +1519,8 @@ ttwakeup(tp)
                tp->t_state &= ~TS_RCOLL;
                tp->t_rsel = 0;
        }
                tp->t_state &= ~TS_RCOLL;
                tp->t_rsel = 0;
        }
+       if (tp->t_state & TS_ASYNC)
+               gsignal(tp->t_pgrp, SIGIO); 
        wakeup((caddr_t)&tp->t_rawq);
 }
 
        wakeup((caddr_t)&tp->t_rawq);
 }
 
index d79ad52..911b3db 100644 (file)
@@ -1,4 +1,4 @@
-/*     tty_bk.c        4.8     82/12/05        */
+/*     tty_bk.c        4.9     83/05/27        */
 
 #include "bk.h"
 
 
 #include "bk.h"
 
@@ -44,7 +44,7 @@ bkopen(dev, tp)
        if (tp->t_line == NETLDISC)
                return (EBUSY); /* sometimes the network opens /dev/tty */
        bp = geteblk(1024);
        if (tp->t_line == NETLDISC)
                return (EBUSY); /* sometimes the network opens /dev/tty */
        bp = geteblk(1024);
-       flushtty(tp, FREAD|FWRITE);
+       ttyflush(tp, FREAD|FWRITE);
        tp->t_bufp = bp;
        tp->t_cp = (char *)bp->b_un.b_addr;
        tp->t_inbuf = 0;
        tp->t_bufp = bp;
        tp->t_cp = (char *)bp->b_un.b_addr;
        tp->t_inbuf = 0;
index d4d0943..76dfecd 100644 (file)
@@ -1,4 +1,4 @@
-/*     tty_conf.c      4.2     82/10/17        */
+/*     tty_conf.c      4.3     83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -52,3 +52,20 @@ struct       linesw linesw[] =
 };
 
 int    nldisp = sizeof (linesw) / sizeof (linesw[0]);
 };
 
 int    nldisp = sizeof (linesw) / sizeof (linesw[0]);
+
+/*
+ * Do nothing specific version of line
+ * discipline specific ioctl command.
+ */
+/*ARGSUSED*/
+nullioctl(tp, cmd, data, flags)
+       struct tty *tp;
+       char *data;
+       int flags;
+{
+
+#ifdef lint
+       tp = tp; data = data; flags = flags;
+#endif
+       return (-1);
+}
index f7b84f0..0bbb7e2 100644 (file)
@@ -1,4 +1,4 @@
-/*     tty_pty.c       4.30    83/05/21        */
+/*     tty_pty.c       4.31    83/05/27        */
 
 /*
  * Pseudo-teletype Driver
 
 /*
  * Pseudo-teletype Driver
@@ -208,7 +208,7 @@ ptcclose(dev)
        if (tp->t_state & TS_ISOPEN)
                gsignal(tp->t_pgrp, SIGHUP);
        tp->t_state &= ~TS_CARR_ON;     /* virtual carrier gone */
        if (tp->t_state & TS_ISOPEN)
                gsignal(tp->t_pgrp, SIGHUP);
        tp->t_state &= ~TS_CARR_ON;     /* virtual carrier gone */
-       flushtty(tp, FREAD|FWRITE);
+       ttyflush(tp, FREAD|FWRITE);
        tp->t_oproc = 0;                /* mark closed */
 }
 
        tp->t_oproc = 0;                /* mark closed */
 }
 
@@ -414,7 +414,7 @@ ptyioctl(dev, cmd, data, flag)
                                pti->pt_flags |= PF_REMOTE;
                        else
                                pti->pt_flags &= ~PF_REMOTE;
                                pti->pt_flags |= PF_REMOTE;
                        else
                                pti->pt_flags &= ~PF_REMOTE;
-                       flushtty(tp, FREAD|FWRITE);
+                       ttyflush(tp, FREAD|FWRITE);
                        return (0);
 
                case FIONBIO:
                        return (0);
 
                case FIONBIO:
index c7be434..edd9a2b 100644 (file)
@@ -1,4 +1,4 @@
-/*     tty_subr.c      4.19    83/02/06        */
+/*     tty_subr.c      4.20    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -13,7 +13,7 @@ char  cwaiting;
  * Character list get/put
  */
 getc(p)
  * Character list get/put
  */
 getc(p)
-register struct clist *p;
+       register struct clist *p;
 {
        register struct cblock *bp;
        register int c, s;
 {
        register struct cblock *bp;
        register int c, s;
@@ -54,6 +54,7 @@ register struct clist *p;
        return(c);
 }
 
        return(c);
 }
 
+#ifdef notdef
 /*
  * copy clist to buffer.
  * return number of bytes moved.
 /*
  * copy clist to buffer.
  * return number of bytes moved.
@@ -109,6 +110,7 @@ q_to_b(q, cp, cc)
        splx(s);
        return(cp-acp);
 }
        splx(s);
        return(cp-acp);
 }
+#endif
 
 /*
  * Return count of contiguous characters
 
 /*
  * Return count of contiguous characters
@@ -156,13 +158,12 @@ out:
  * Flush cc bytes from q.
  */
 ndflush(q, cc)
  * Flush cc bytes from q.
  */
 ndflush(q, cc)
-register struct clist *q;
-register cc;
+       register struct clist *q;
+       register cc;
 {
 {
-register struct cblock *bp;
-char *end;
-int rem;
-register s;
+       register struct cblock *bp;
+       char *end;
+       int rem, s;
 
        s = spl5();
        if (q->c_cc <= 0) {
 
        s = spl5();
        if (q->c_cc <= 0) {
@@ -212,7 +213,7 @@ out:
 
 
 putc(c, p)
 
 
 putc(c, p)
-register struct clist *p;
+       register struct clist *p;
 {
        register struct cblock *bp;
        register char *cp;
 {
        register struct cblock *bp;
        register char *cp;
@@ -254,9 +255,9 @@ register struct clist *p;
  * return number of bytes not transfered.
  */
 b_to_q(cp, cc, q)
  * return number of bytes not transfered.
  */
 b_to_q(cp, cc, q)
-register char *cp;
-struct clist *q;
-register int cc;
+       register char *cp;
+       struct clist *q;
+       register int cc;
 {
        register char *cq;
        register struct cblock *bp;
 {
        register char *cq;
        register struct cblock *bp;
@@ -308,8 +309,8 @@ out:
  */
 char *
 nextc(p, cp)
  */
 char *
 nextc(p, cp)
-register struct clist *p;
-register char *cp;
+       register struct clist *p;
+       register char *cp;
 {
 
        if (p->c_cc && ++cp != p->c_cl) {
 {
 
        if (p->c_cc && ++cp != p->c_cl) {
@@ -324,7 +325,7 @@ register char *cp;
  * Remove the last character in the list and return it.
  */
 unputc(p)
  * Remove the last character in the list and return it.
  */
 unputc(p)
-register struct clist *p;
+       register struct clist *p;
 {
        register struct cblock *bp;
        register int c, s;
 {
        register struct cblock *bp;
        register int c, s;
@@ -368,7 +369,7 @@ register struct clist *p;
  * SHOULD JUST USE q_to_b AND THEN b_to_q HERE.
  */
 catq(from, to)
  * SHOULD JUST USE q_to_b AND THEN b_to_q HERE.
  */
 catq(from, to)
-struct clist *from, *to;
+       struct clist *from, *to;
 {
        register c;
 
 {
        register c;
 
index 90dae83..49cfcda 100644 (file)
@@ -1,4 +1,4 @@
-/*     tty_tb.c        4.7     82/12/05        */
+/*     tty_tb.c        4.8     83/05/27        */
 
 #include "tb.h"
 #if NTB > 0
 
 #include "tb.h"
 #if NTB > 0
@@ -48,7 +48,7 @@ tbopen(dev, tp)
 
        if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) {
                return (EBUSY);
 
        if (tp->t_line == TABLDISC || tp->t_line == NTABLDISC) {
                return (EBUSY);
-       wflushtty(tp);
+       ttywflush(tp);
        tp->t_cp = (char *) &tp->t_un.T_CTLQ;   /* overlay control queue */
        tp->t_inbuf = 0;
        tbp = (struct tbposition *) &tp->t_rocount;
        tp->t_cp = (char *) &tp->t_un.T_CTLQ;   /* overlay control queue */
        tp->t_inbuf = 0;
        tbp = (struct tbposition *) &tp->t_rocount;
index d7b1ffe..11f5f9b 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_mbuf.c     1.42    82/12/17        */
+/*     uipc_mbuf.c     1.43    83/05/27        */
 
 #include "../machine/pte.h"
 
 
 #include "../machine/pte.h"
 
index d7f5684..70fb681 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_proto.c    4.27    82/11/02        */
+/*     uipc_proto.c    4.28    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/socket.h"
 
 #include "../h/param.h"
 #include "../h/socket.h"
@@ -19,7 +19,7 @@ struct protosw unixsw[] = {
   uipc_usrreq,
   0,           0,              0,              0,
 },
   uipc_usrreq,
   0,           0,              0,              0,
 },
-{ SOCK_DGRAM,  PF_UNIX,        0,              PR_ATOMIC|PR_ADDR,
+{ SOCK_DGRAM,  PF_UNIX,        0,              PR_ATOMIC|PR_ADDR|PR_RIGHTS,
   0,           0,              0,              0,
   uipc_usrreq,
   0,           0,              0,              0,
   0,           0,              0,              0,
   uipc_usrreq,
   0,           0,              0,              0,
index b1117da..2e1ef22 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_socket.c   4.74    83/05/18        */
+/*     uipc_socket.c   4.75    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -9,6 +9,7 @@
 #include "../h/inode.h"
 #include "../h/buf.h"
 #include "../h/mbuf.h"
 #include "../h/inode.h"
 #include "../h/buf.h"
 #include "../h/mbuf.h"
+#include "../h/un.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
@@ -16,6 +17,7 @@
 #include "../h/ioctl.h"
 #include "../h/uio.h"
 #include "../net/route.h"
 #include "../h/ioctl.h"
 #include "../h/uio.h"
 #include "../net/route.h"
+#include "../netinet/in.h"
 #include "../net/if.h"
 
 /*
 #include "../net/if.h"
 
 /*
  * sys_socket.c or from a system process, and
  * implement the semantics of socket operations by
  * switching out to the protocol specific routines.
  * sys_socket.c or from a system process, and
  * implement the semantics of socket operations by
  * switching out to the protocol specific routines.
+ *
+ * TODO:
+ *     sostat
+ *     test socketpair
+ *     PR_RIGHTS
+ *     clean up select, async
+ *     out-of-band is a kludge
  */
  */
-
 /*ARGSUSED*/
 socreate(dom, aso, type, proto)
        struct socket **aso;
 /*ARGSUSED*/
 socreate(dom, aso, type, proto)
        struct socket **aso;
-       int type, proto;
+       register int type;
+       int proto;
 {
        register struct protosw *prp;
        register struct socket *so;
 {
        register struct protosw *prp;
        register struct socket *so;
-       struct mbuf *m;
-       int error;
+       register struct mbuf *m;
+       register int error;
 
        if (proto)
                prp = pffindproto(dom, proto);
 
        if (proto)
                prp = pffindproto(dom, proto);
@@ -48,14 +57,15 @@ socreate(dom, aso, type, proto)
        if (m == 0)
                return (ENOBUFS);
        so = mtod(m, struct socket *);
        if (m == 0)
                return (ENOBUFS);
        so = mtod(m, struct socket *);
-       so->so_options = SO_LINGER;
+       so->so_options = 0;
        so->so_state = 0;
        so->so_type = type;
        if (u.u_uid == 0)
                so->so_state = SS_PRIV;
        so->so_proto = prp;
        so->so_state = 0;
        so->so_type = type;
        if (u.u_uid == 0)
                so->so_state = SS_PRIV;
        so->so_proto = prp;
-       error = (*prp->pr_usrreq)(so, PRU_ATTACH,
-           (struct mbuf *)0, (struct mbuf *)0);
+       error =
+           (*prp->pr_usrreq)(so, PRU_ATTACH,
+               (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
        if (error) {
                so->so_state |= SS_NOFDREF;
                sofree(so);
        if (error) {
                so->so_state |= SS_NOFDREF;
                sofree(so);
@@ -73,20 +83,21 @@ sobind(so, nam)
        int error;
 
        error =
        int error;
 
        error =
-           (*so->so_proto->pr_usrreq)(so, PRU_BIND, (struct mbuf *)0, nam);
+           (*so->so_proto->pr_usrreq)(so, PRU_BIND,
+               (struct mbuf *)0, nam, (struct mbuf *)0);
        splx(s);
        return (error);
 }
 
 solisten(so, backlog)
        splx(s);
        return (error);
 }
 
 solisten(so, backlog)
-       struct socket *so;
+       register struct socket *so;
        int backlog;
 {
        int backlog;
 {
-       int s = splnet();
-       int error;
+       int s = splnet(), error;
 
 
-       error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN,
-           (struct mbuf *)0, (struct mbuf *)0);
+       error =
+           (*so->so_proto->pr_usrreq)(so, PRU_LISTEN,
+               (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
        if (error) {
                splx(s);
                return (error);
        if (error) {
                splx(s);
                return (error);
@@ -98,15 +109,13 @@ solisten(so, backlog)
        }
        if (backlog < 0)
                backlog = 0;
        }
        if (backlog < 0)
                backlog = 0;
-#define        SOMAXCONN       5
        so->so_qlimit = MIN(backlog, SOMAXCONN);
        so->so_qlimit = MIN(backlog, SOMAXCONN);
-       so->so_options |= SO_NEWFDONCONN;
        splx(s);
        return (0);
 }
 
 sofree(so)
        splx(s);
        return (0);
 }
 
 sofree(so)
-       struct socket *so;
+       register struct socket *so;
 {
 
        if (so->so_head) {
 {
 
        if (so->so_head) {
@@ -117,7 +126,7 @@ sofree(so)
        if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
                return;
        sbrelease(&so->so_snd);
        if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
                return;
        sbrelease(&so->so_snd);
-       sbrelease(&so->so_rcv);
+       sorflush(so);
        (void) m_free(dtom(so));
 }
 
        (void) m_free(dtom(so));
 }
 
@@ -126,9 +135,8 @@ sofree(so)
  * Initiate disconnect if connected.
  * Free socket when disconnect complete.
  */
  * Initiate disconnect if connected.
  * Free socket when disconnect complete.
  */
-soclose(so, exiting)
+soclose(so)
        register struct socket *so;
        register struct socket *so;
-       int exiting;
 {
        int s = splnet();               /* conservative */
        int error;
 {
        int s = splnet();               /* conservative */
        int error;
@@ -141,36 +149,27 @@ soclose(so, exiting)
        }
        if (so->so_pcb == 0)
                goto discard;
        }
        if (so->so_pcb == 0)
                goto discard;
-       if (exiting)
-               so->so_options |= SO_KEEPALIVE;
        if (so->so_state & SS_ISCONNECTED) {
                if ((so->so_state & SS_ISDISCONNECTING) == 0) {
                        error = sodisconnect(so, (struct mbuf *)0);
        if (so->so_state & SS_ISCONNECTED) {
                if ((so->so_state & SS_ISDISCONNECTING) == 0) {
                        error = sodisconnect(so, (struct mbuf *)0);
-                       if (error) {
-                               if (exiting)
-                                       goto drop;
-                               splx(s);
-                               return (error);
-                       }
+                       if (error)
+                               goto drop;
                }
                if (so->so_options & SO_LINGER) {
                        if ((so->so_state & SS_ISDISCONNECTING) &&
                }
                if (so->so_options & SO_LINGER) {
                        if ((so->so_state & SS_ISDISCONNECTING) &&
-                           (so->so_state & SS_NBIO) &&
-                           exiting == 0)
-                               return (EINPROGRESS);
-                       /* should use tsleep here, for at most linger */
+                           (so->so_state & SS_NBIO))
+                               goto drop;
                        while (so->so_state & SS_ISCONNECTED)
                                sleep((caddr_t)&so->so_timeo, PZERO+1);
                }
        }
 drop:
        if (so->so_pcb) {
                        while (so->so_state & SS_ISCONNECTED)
                                sleep((caddr_t)&so->so_timeo, PZERO+1);
                }
        }
 drop:
        if (so->so_pcb) {
-               error = (*so->so_proto->pr_usrreq)(so, PRU_DETACH,
-                   (struct mbuf *)0, (struct mbuf *)0);
-               if (exiting == 0 && error) {
-                       splx(s);
-                       return (error);
-               }
+               int error2 =
+                   (*so->so_proto->pr_usrreq)(so, PRU_DETACH,
+                       (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
+               if (error == 0)
+                       error = error2;
        }
 discard:
        if (so->so_state & SS_NOFDREF)
        }
 discard:
        if (so->so_state & SS_NOFDREF)
@@ -178,7 +177,7 @@ discard:
        so->so_state |= SS_NOFDREF;
        sofree(so);
        splx(s);
        so->so_state |= SS_NOFDREF;
        sofree(so);
        splx(s);
-       return (0);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -187,27 +186,14 @@ discard:
 soabort(so)
        struct socket *so;
 {
 soabort(so)
        struct socket *so;
 {
-       int error;
 
 
-       error = (*so->so_proto->pr_usrreq)(so, PRU_ABORT,
-          (struct mbuf *)0, (struct mbuf *)0);
-       return (error);
-}
-
-/*ARGSUSED*/
-sostat(so, ub)
-       struct socket *so;
-       struct stat *ub;
-{
-       struct stat sb;
-
-       bzero((caddr_t)&sb, sizeof (sb));               /* XXX */
-       (void) copyout((caddr_t)&sb, (caddr_t)ub, sizeof (sb));/* XXX */
-       return (0);                                     /* XXX */
+       return (
+           (*so->so_proto->pr_usrreq)(so, PRU_ABORT,
+               (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
 }
 
 soaccept(so, nam)
 }
 
 soaccept(so, nam)
-       struct socket *so;
+       register struct socket *so;
        struct mbuf *nam;
 {
        int s = splnet();
        struct mbuf *nam;
 {
        int s = splnet();
@@ -217,13 +203,13 @@ soaccept(so, nam)
                panic("soaccept: !NOFDREF");
        so->so_state &= ~SS_NOFDREF;
        error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT,
                panic("soaccept: !NOFDREF");
        so->so_state &= ~SS_NOFDREF;
        error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT,
-           (struct mbuf *)0, nam);
+           (struct mbuf *)0, nam, (struct mbuf *)0);
        splx(s);
        return (error);
 }
 
 soconnect(so, nam)
        splx(s);
        return (error);
 }
 
 soconnect(so, nam)
-       struct socket *so;
+       register struct socket *so;
        struct mbuf *nam;
 {
        int s = splnet();
        struct mbuf *nam;
 {
        int s = splnet();
@@ -234,14 +220,30 @@ soconnect(so, nam)
                goto bad;
        }
        error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
                goto bad;
        }
        error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
-           (struct mbuf *)0, nam);
+           (struct mbuf *)0, nam, (struct mbuf *)0);
 bad:
        splx(s);
        return (error);
 }
 
 bad:
        splx(s);
        return (error);
 }
 
+#ifdef notdef
+soconnect2(so1, so2)
+       register struct socket *so1;
+       struct socket *so2;
+{
+       int s = splnet();
+       int error;
+
+       error =
+           (*so1->so_proto->pr_usrreq)(so, PRU_CONNECT2,
+               (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0);
+       splx(s);
+       return (error);
+}
+#endif
+
 sodisconnect(so, nam)
 sodisconnect(so, nam)
-       struct socket *so;
+       register struct socket *so;
        struct mbuf *nam;
 {
        int s = splnet();
        struct mbuf *nam;
 {
        int s = splnet();
@@ -256,7 +258,7 @@ sodisconnect(so, nam)
                goto bad;
        }
        error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
                goto bad;
        }
        error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
-           (struct mbuf *)0, nam);
+           (struct mbuf *)0, nam, (struct mbuf *)0);
 bad:
        splx(s);
        return (error);
 bad:
        splx(s);
        return (error);
@@ -270,22 +272,23 @@ bad:
  * If must go all at once and not enough room now, then
  * inform user that this would block and do nothing.
  */
  * If must go all at once and not enough room now, then
  * inform user that this would block and do nothing.
  */
-sosend(so, nam, uio, flags)
+sosend(so, nam, uio, flags, rights)
        register struct socket *so;
        struct mbuf *nam;
        register struct socket *so;
        struct mbuf *nam;
-       struct uio *uio;
+       register struct uio *uio;
        int flags;
        int flags;
+       struct mbuf *rights;
 {
        struct mbuf *top = 0;
        register struct mbuf *m, **mp = &top;
 {
        struct mbuf *top = 0;
        register struct mbuf *m, **mp = &top;
-       register int len;
-       int error = 0, space, s, dontroute;
+       register int space;
+       int len, error = 0, s, dontroute;
 
        if (sosendallatonce(so) && uio->uio_resid > so->so_snd.sb_hiwat)
                return (EMSGSIZE);
 
        if (sosendallatonce(so) && uio->uio_resid > so->so_snd.sb_hiwat)
                return (EMSGSIZE);
-       dontroute = (flags & SOF_DONTROUTE) &&
-               (so->so_options & SO_DONTROUTE) == 0 &&
-               (so->so_proto->pr_flags & PR_ATOMIC);
+       dontroute =
+           (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
+           (so->so_proto->pr_flags & PR_ATOMIC);
 restart:
        sblock(&so->so_snd);
 #define        snderr(errno)   { error = errno; splx(s); goto release; }
 restart:
        sblock(&so->so_snd);
 #define        snderr(errno)   { error = errno; splx(s); goto release; }
@@ -313,8 +316,8 @@ again:
                if (dontroute)
                        so->so_options |= SO_DONTROUTE;
                error = (*so->so_proto->pr_usrreq)(so,
                if (dontroute)
                        so->so_options |= SO_DONTROUTE;
                error = (*so->so_proto->pr_usrreq)(so,
-                   (flags & SOF_OOB) ? PRU_SENDOOB : PRU_SEND,
-                   top, (caddr_t)nam);
+                   (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
+                   top, (caddr_t)nam, rights);
                if (dontroute)
                        so->so_options &= ~SO_DONTROUTE;
                top = 0;
                if (dontroute)
                        so->so_options &= ~SO_DONTROUTE;
                top = 0;
@@ -328,7 +331,7 @@ again:
                splx(s);
                goto release;
        }
                splx(s);
                goto release;
        }
-       if (flags & SOF_OOB)
+       if (flags & MSG_OOB)
                space = 1024;
        else {
                space = sbspace(&so->so_snd);
                space = 1024;
        else {
                space = sbspace(&so->so_snd);
@@ -373,7 +376,7 @@ nopages:
                m->m_len = len;
                *mp = m;
                mp = &m->m_next;
                m->m_len = len;
                *mp = m;
                mp = &m->m_next;
-               if (flags & SOF_OOB)
+               if (flags & MSG_OOB)
                        space -= len;
                else
                        space = sbspace(&so->so_snd);
                        space -= len;
                else
                        space = sbspace(&so->so_snd);
@@ -387,22 +390,28 @@ release:
        return (error);
 }
 
        return (error);
 }
 
-soreceive(so, aname, uio, flags)
+soreceive(so, aname, uio, flags, rightsp)
        register struct socket *so;
        struct mbuf **aname;
        register struct socket *so;
        struct mbuf **aname;
-       struct uio *uio;
+       register struct uio *uio;
        int flags;
        int flags;
+       struct mbuf **rightsp;
 {
        register struct mbuf *m, *n;
 {
        register struct mbuf *m, *n;
-       int len;
-       int eor, s, error = 0, moff, tomark;
-
-       if (flags & SOF_OOB) {
+       register int len, error = 0, s, eor, tomark;
+       struct protosw *pr = so->so_proto;
+       int moff;
+
+       if (rightsp)
+               *rightsp = 0;
+       if (aname)
+               *aname = 0;
+       if (flags & MSG_OOB) {
                m = m_get(M_WAIT, MT_DATA);
                m = m_get(M_WAIT, MT_DATA);
-               if (m == NULL)
+               if (m == 0)
                        return (ENOBUFS);
                        return (ENOBUFS);
-               error = (*so->so_proto->pr_usrreq)(so, PRU_RCVOOB,
-                   m, (struct mbuf *)0);
+               error = (*pr->pr_usrreq)(so, PRU_RCVOOB,
+                   m, (struct mbuf *)0, (struct mbuf *)0);
                if (error)
                        goto bad;
                do {
                if (error)
                        goto bad;
                do {
@@ -449,13 +458,13 @@ restart:
        m = so->so_rcv.sb_mb;
        if (m == 0)
                panic("receive");
        m = so->so_rcv.sb_mb;
        if (m == 0)
                panic("receive");
-       if (so->so_proto->pr_flags & PR_ADDR) {
-               if ((flags & SOF_PREVIEW) == 0) {
+       if (pr->pr_flags & PR_ADDR) {
+               if ((flags & MSG_PEEK) == 0) {
                        so->so_rcv.sb_cc -= m->m_len;
                        so->so_rcv.sb_mbcnt -= MSIZE;
                }
                if (aname) {
                        so->so_rcv.sb_cc -= m->m_len;
                        so->so_rcv.sb_mbcnt -= MSIZE;
                }
                if (aname) {
-                       if (flags & SOF_PREVIEW) {
+                       if (flags & MSG_PEEK) {
                                *aname = m_copy(m, 0, m->m_len);
                                if (*aname == NULL)
                                        panic("receive 2");
                                *aname = m_copy(m, 0, m->m_len);
                                if (*aname == NULL)
                                        panic("receive 2");
@@ -464,13 +473,33 @@ restart:
                        m = m->m_next;
                        (*aname)->m_next = 0;
                } else
                        m = m->m_next;
                        (*aname)->m_next = 0;
                } else
-                       if (flags & SOF_PREVIEW)
+                       if (flags & MSG_PEEK)
                                m = m->m_next;
                        else
                                m = m_free(m);
                                m = m->m_next;
                        else
                                m = m_free(m);
+               if (m == 0)
+                       panic("receive 2a");
+               if (rightsp) {
+                       if (m->m_len)
+                               *rightsp = m_copy(m, 0, m->m_len);
+                       else {
+                               *rightsp = m_get(M_DONTWAIT, MT_SONAME);
+                               if (*rightsp)
+                                       (*rightsp)->m_len = 0;
+                       }
+                       if (*rightsp == NULL)
+                               panic("receive 2b");
+               }
+               if (flags & MSG_PEEK)
+                       m = m->m_next;
+               else {
+                       so->so_rcv.sb_cc -= m->m_len;
+                       so->so_rcv.sb_mbcnt -= MSIZE;
+                       m = m_free(m);
+               }
                if (m == 0)
                        panic("receive 3");
                if (m == 0)
                        panic("receive 3");
-               if ((flags & SOF_PREVIEW) == 0)
+               if ((flags & MSG_PEEK) == 0)
                        so->so_rcv.sb_mb = m;
        }
        eor = 0;
                        so->so_rcv.sb_mb = m;
        }
        eor = 0;
@@ -491,7 +520,7 @@ restart:
                s = splnet();
                if (len == m->m_len) {
                        eor = (int)m->m_act;
                s = splnet();
                if (len == m->m_len) {
                        eor = (int)m->m_act;
-                       if (flags & SOF_PREVIEW)
+                       if (flags & MSG_PEEK)
                                m = m->m_next;
                        else {
                                sbfree(&so->so_rcv, m);
                                m = m->m_next;
                        else {
                                sbfree(&so->so_rcv, m);
@@ -501,7 +530,7 @@ restart:
                        }
                        moff = 0;
                } else {
                        }
                        moff = 0;
                } else {
-                       if (flags & SOF_PREVIEW)
+                       if (flags & MSG_PEEK)
                                moff += len;
                        else {
                                m->m_off += len;
                                moff += len;
                        else {
                                m->m_off += len;
@@ -509,7 +538,7 @@ restart:
                                so->so_rcv.sb_cc -= len;
                        }
                }
                                so->so_rcv.sb_cc -= len;
                        }
                }
-               if ((flags & SOF_PREVIEW) == 0 && so->so_oobmark) {
+               if ((flags & MSG_PEEK) == 0 && so->so_oobmark) {
                        so->so_oobmark -= len;
                        if (so->so_oobmark == 0) {
                                so->so_state |= SS_RCVATMARK;
                        so->so_oobmark -= len;
                        if (so->so_oobmark == 0) {
                                so->so_state |= SS_RCVATMARK;
@@ -522,7 +551,7 @@ restart:
                                break;
                }
        } while (m && error == 0 && !eor);
                                break;
                }
        } while (m && error == 0 && !eor);
-       if (flags & SOF_PREVIEW)
+       if (flags & MSG_PEEK)
                goto release;
        if ((so->so_proto->pr_flags & PR_ATOMIC) && eor == 0)
                do {
                goto release;
        if ((so->so_proto->pr_flags & PR_ATOMIC) && eor == 0)
                do {
@@ -536,35 +565,55 @@ restart:
                } while (eor == 0);
        if ((so->so_proto->pr_flags & PR_WANTRCVD) && so->so_pcb)
                (*so->so_proto->pr_usrreq)(so, PRU_RCVD,
                } while (eor == 0);
        if ((so->so_proto->pr_flags & PR_WANTRCVD) && so->so_pcb)
                (*so->so_proto->pr_usrreq)(so, PRU_RCVD,
-                   (struct mbuf *)0, (struct mbuf *)0);
+                   (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
 release:
        sbunlock(&so->so_rcv);
 release:
        sbunlock(&so->so_rcv);
+       if (error == 0 && rightsp &&
+           *rightsp && so->so_proto->pr_family == AF_UNIX)
+               error = unp_externalize(*rightsp);
        splx(s);
        return (error);
 }
 
 soshutdown(so, how)
        splx(s);
        return (error);
 }
 
 soshutdown(so, how)
-       struct socket *so;
-       int how;
+       register struct socket *so;
+       register int how;
 {
 {
+       register struct protosw *pr = so->so_proto;
 
        how++;
 
        how++;
-       if (how & FREAD) {
-               int s = splimp();
-               socantrcvmore(so);
-               sbflush(&so->so_rcv);
-               splx(s);
-       }
+       if (how & FREAD)
+               sorflush(so);
        if (how & FWRITE)
        if (how & FWRITE)
-               return ((*so->so_proto->pr_usrreq)(so, PRU_SHUTDOWN,
-                   (struct mbuf *)0, (struct mbuf *)0));
+               return ((*pr->pr_usrreq)(so, PRU_SHUTDOWN,
+                   (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
        return (0);
 }
 
        return (0);
 }
 
+sorflush(so)
+       register struct socket *so;
+{
+       register struct sockbuf *sb = &so->so_rcv;
+       register struct protosw *pr = so->so_proto;
+       register int s;
+       struct sockbuf asb;
+
+       sblock(sb);
+       s = splimp();
+       socantrcvmore(so);
+       sbunlock(sb);
+       asb = *sb;
+       bzero((caddr_t)sb, sizeof (*sb));
+       splx(s);
+       if (pr->pr_family == AF_UNIX && (pr->pr_flags & PR_RIGHTS))
+               unp_scan(asb.sb_mb, unp_discard);
+       sbrelease(&asb);
+}
+
 sosetopt(so, level, optname, m)
 sosetopt(so, level, optname, m)
-       struct socket *so;
+       register struct socket *so;
        int level, optname;
        int level, optname;
-       struct mbuf *m;
+       register struct mbuf *m;
 {
 
        if (level != SOL_SOCKET)
 {
 
        if (level != SOL_SOCKET)
@@ -598,9 +647,9 @@ sosetopt(so, level, optname, m)
 }
 
 sogetopt(so, level, optname, m)
 }
 
 sogetopt(so, level, optname, m)
-       struct socket *so;
+       register struct socket *so;
        int level, optname;
        int level, optname;
-       struct mbuf *m;
+       register struct mbuf *m;
 {
 
        if (level != SOL_SOCKET)
 {
 
        if (level != SOL_SOCKET)
@@ -628,7 +677,7 @@ sogetopt(so, level, optname, m)
 }
 
 sohasoutofband(so)
 }
 
 sohasoutofband(so)
-       struct socket *so;
+       register struct socket *so;
 {
 
        if (so->so_pgrp == 0)
 {
 
        if (so->so_pgrp == 0)
@@ -642,68 +691,3 @@ sohasoutofband(so)
                        psignal(p, SIGURG);
        }
 }
                        psignal(p, SIGURG);
        }
 }
-
-/*ARGSUSED*/
-soioctl(so, cmd, data)
-       register struct socket *so;
-       int cmd;
-       register char *data;
-{
-
-       switch (cmd) {
-
-       case FIONBIO:
-               if (*(int *)data)
-                       so->so_state |= SS_NBIO;
-               else
-                       so->so_state &= ~SS_NBIO;
-               break;
-
-       case FIOASYNC:
-               if (*(int *)data)
-                       so->so_state |= SS_ASYNC;
-               else
-                       so->so_state &= ~SS_ASYNC;
-               break;
-
-       case SIOCSPGRP:
-               so->so_pgrp = *(int *)data;
-               break;
-
-       case SIOCGPGRP:
-               *(int *)data = so->so_pgrp;
-               break;
-
-       case SIOCATMARK:
-               *(int *)data = (so->so_state&SS_RCVATMARK) != 0;
-               break;
-
-       /* routing table update calls */
-       case SIOCADDRT:
-       case SIOCDELRT:
-               if (!suser())
-                       return (u.u_error);
-               return (rtrequest(cmd, (struct rtentry *)data));
-
-       /* interface parameter requests */
-       case SIOCSIFADDR:
-       case SIOCSIFFLAGS:
-       case SIOCSIFDSTADDR:
-               if (!suser())
-                       return (u.u_error);
-               return (ifrequest(cmd, data));
-
-       case SIOCGIFADDR:
-       case SIOCGIFFLAGS:
-       case SIOCGIFDSTADDR:
-               return (ifrequest(cmd, data));
-
-       case SIOCGIFCONF:
-               return (ifconf(cmd, data));
-
-       /* type/protocol specific ioctls */
-       default:
-               return (ENOTTY);                /* XXX */
-       }
-       return (0);
-}
index 19ea2a8..716be26 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_socket2.c  4.36    83/05/01        */
+/*     uipc_socket2.c  4.37    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
  * only, bypassing the in-progress calls when setting up a ``connection''
  * takes no time.
  *
  * only, bypassing the in-progress calls when setting up a ``connection''
  * takes no time.
  *
- * From the passive side, a socket is created with SO_ACCEPTCONN
- * creating two queues of sockets: so_q0 for connections in progress
+ * From the passive side, a socket is created with
+ * two queues of sockets: so_q0 for connections in progress
  * and so_q for connections already made and awaiting user acceptance.
  * As a protocol is preparing incoming connections, it creates a socket
  * structure queued on so_q0 by calling sonewconn().  When the connection
  * is established, soisconnected() is called, and transfers the
  * socket structure to so_q, making it available to accept().
  * 
  * and so_q for connections already made and awaiting user acceptance.
  * As a protocol is preparing incoming connections, it creates a socket
  * structure queued on so_q0 by calling sonewconn().  When the connection
  * is established, soisconnected() is called, and transfers the
  * socket structure to so_q, making it available to accept().
  * 
- * If a SO_ACCEPTCONN socket is closed with sockets on either
+ * If a socket is closed with sockets on either
  * so_q0 or so_q, these sockets are dropped.
  *
  * so_q0 or so_q, these sockets are dropped.
  *
- * If and when higher level protocols are implemented in
+ * If higher level protocols are implemented in
  * the kernel, the wakeups done here will sometimes
  * the kernel, the wakeups done here will sometimes
- * be implemented as software-interrupt process scheduling.
+ * cause software-interrupt process scheduling.
  */
 
 soisconnecting(so)
  */
 
 soisconnecting(so)
-       struct socket *so;
+       register struct socket *so;
 {
 
        so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
 {
 
        so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
@@ -57,7 +57,7 @@ soisconnecting(so)
 }
 
 soisconnected(so)
 }
 
 soisconnected(so)
-       struct socket *so;
+       register struct socket *so;
 {
        register struct socket *head = so->so_head;
 
 {
        register struct socket *head = so->so_head;
 
@@ -65,8 +65,8 @@ soisconnected(so)
                if (soqremque(so, 0) == 0)
                        panic("soisconnected");
                soqinsque(head, so, 1);
                if (soqremque(so, 0) == 0)
                        panic("soisconnected");
                soqinsque(head, so, 1);
-               wakeup((caddr_t)&head->so_timeo);
                sorwakeup(head);
                sorwakeup(head);
+               wakeup((caddr_t)&head->so_timeo);
        }
        so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING);
        so->so_state |= SS_ISCONNECTED;
        }
        so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING);
        so->so_state |= SS_ISCONNECTED;
@@ -76,7 +76,7 @@ soisconnected(so)
 }
 
 soisdisconnecting(so)
 }
 
 soisdisconnecting(so)
-       struct socket *so;
+       register struct socket *so;
 {
 
        so->so_state &= ~SS_ISCONNECTING;
 {
 
        so->so_state &= ~SS_ISCONNECTING;
@@ -87,7 +87,7 @@ soisdisconnecting(so)
 }
 
 soisdisconnected(so)
 }
 
 soisdisconnected(so)
-       struct socket *so;
+       register struct socket *so;
 {
 
        so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
 {
 
        so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
@@ -109,7 +109,7 @@ sonewconn(head)
        register struct socket *head;
 {
        register struct socket *so;
        register struct socket *head;
 {
        register struct socket *so;
-       struct mbuf *m;
+       register struct mbuf *m;
 
        if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2)
                goto bad;
 
        if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2)
                goto bad;
@@ -125,8 +125,8 @@ sonewconn(head)
        so->so_timeo = head->so_timeo;
        so->so_pgrp = head->so_pgrp;
        soqinsque(head, so, 0);
        so->so_timeo = head->so_timeo;
        so->so_pgrp = head->so_pgrp;
        soqinsque(head, so, 0);
-       if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, (struct mbuf *)0,
-         (struct mbuf *)0)) {
+       if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH,
+           (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) {
                (void) soqremque(so, 0);
                (void) m_free(m);
                goto bad;
                (void) soqremque(so, 0);
                (void) m_free(m);
                goto bad;
@@ -211,38 +211,6 @@ socantrcvmore(so)
  * Socket select/wakeup routines.
  */
 
  * Socket select/wakeup routines.
  */
 
-/*
- * Interface routine to select() system
- * call for sockets.
- */
-soselect(so, rw)
-       register struct socket *so;
-       int rw;
-{
-       int s = splnet();
-
-       switch (rw) {
-
-       case FREAD:
-               if (soreadable(so)) {
-                       splx(s);
-                       return (1);
-               }
-               sbselqueue(&so->so_rcv);
-               break;
-
-       case FWRITE:
-               if (sowriteable(so)) {
-                       splx(s);
-                       return (1);
-               }
-               sbselqueue(&so->so_snd);
-               break;
-       }
-       splx(s);
-       return (0);
-}
-
 /*
  * Queue a process for a select on a socket buffer.
  */
 /*
  * Queue a process for a select on a socket buffer.
  */
@@ -272,7 +240,7 @@ sbwait(sb)
  * Wakeup processes waiting on a socket buffer.
  */
 sbwakeup(sb)
  * Wakeup processes waiting on a socket buffer.
  */
 sbwakeup(sb)
-       struct sockbuf *sb;
+       register struct sockbuf *sb;
 {
 
        if (sb->sb_sel) {
 {
 
        if (sb->sb_sel) {
@@ -325,7 +293,7 @@ sbwakeup(sb)
  */
 
 soreserve(so, sndcc, rcvcc)
  */
 
 soreserve(so, sndcc, rcvcc)
-       struct socket *so;
+       register struct socket *so;
        int sndcc, rcvcc;
 {
 
        int sndcc, rcvcc;
 {
 
@@ -349,8 +317,8 @@ sbreserve(sb, cc)
 
        /* someday maybe this routine will fail... */
        sb->sb_hiwat = cc;
 
        /* someday maybe this routine will fail... */
        sb->sb_hiwat = cc;
-       /* the 2 implies names can be no more than 1 mbuf each */
-       sb->sb_mbmax = cc*2;
+       /* * 2 implies names can be no more than 1 mbuf each */
+       sb->sb_mbmax = cc<<1;
        return (1);
 }
 
        return (1);
 }
 
@@ -414,15 +382,17 @@ sbappend(sb, m)
  * Return 0 if no space in sockbuf or if
  * can't get mbuf to stuff address in.
  */
  * Return 0 if no space in sockbuf or if
  * can't get mbuf to stuff address in.
  */
-sbappendaddr(sb, asa, m0)
+sbappendaddr(sb, asa, m0, rights0)
        struct sockbuf *sb;
        struct sockaddr *asa;
        struct sockbuf *sb;
        struct sockaddr *asa;
-       struct mbuf *m0;
+       struct mbuf *m0, *rights0;
 {
 {
-       struct sockaddr *msa;
        register struct mbuf *m;
        register int len = sizeof (struct sockaddr);
        register struct mbuf *m;
        register int len = sizeof (struct sockaddr);
+       register struct mbuf *rights;
 
 
+       if (rights0)
+               len += rights0->m_len;
        m = m0;
        if (m == 0)
                panic("sbappendaddr");
        m = m0;
        if (m == 0)
                panic("sbappendaddr");
@@ -437,45 +407,34 @@ sbappendaddr(sb, asa, m0)
        if (len > sbspace(sb))
                return (0);
        m = m_get(M_DONTWAIT, MT_SONAME);
        if (len > sbspace(sb))
                return (0);
        m = m_get(M_DONTWAIT, MT_SONAME);
-       if (m == 0)
+       if (m == NULL)
                return (0);
        m->m_len = sizeof (struct sockaddr);
                return (0);
        m->m_len = sizeof (struct sockaddr);
-       msa = mtod(m, struct sockaddr *);
-       *msa = *asa;
        m->m_act = (struct mbuf *)1;
        m->m_act = (struct mbuf *)1;
+       *mtod(m, struct sockaddr *) = *asa;
+       if (rights0 == 0 || rights0->m_len == 0) {
+               rights = m_get(M_DONTWAIT, MT_SONAME);
+               if (rights)
+                       rights->m_len = 0;
+       } else
+               rights = m_copy(rights0, 0, rights0->m_len);
+       if (rights == 0) {
+               m_freem(m);
+               return (0);
+       }
+       rights->m_act = (struct mbuf *)1;
+       m->m_next = rights;
+       rights->m_next = m0;
        sbappend(sb, m);
        sbappend(sb, m);
-       sbappend(sb, m0);
        return (1);
 }
 
        return (1);
 }
 
-#ifdef notdef
-SBCHECK(sb, str)
-       struct sockbuf *sb;
-       char *str;
-{
-       register int cnt = sb->sb_cc;
-       register int mbcnt = sb->sb_mbcnt;
-       register struct mbuf *m;
-
-       for (m = sb->sb_mb; m; m = m->m_next) {
-               cnt -= m->m_len;
-               mbcnt -= MSIZE;
-               if (m->m_off > MMAXOFF)
-                       mbcnt -= CLBYTES;
-       }
-       if (cnt || mbcnt) {
-               printf("cnt %d mbcnt %d\n", cnt, mbcnt);
-               panic(str);
-       }
-}
-#endif
-
 /*
  * Free all mbufs on a sockbuf mbuf chain.
  * Check that resource allocations return to 0.
  */
 sbflush(sb)
 /*
  * Free all mbufs on a sockbuf mbuf chain.
  * Check that resource allocations return to 0.
  */
 sbflush(sb)
-       struct sockbuf *sb;
+       register struct sockbuf *sb;
 {
 
        if (sb->sb_flags & SB_LOCK)
 {
 
        if (sb->sb_flags & SB_LOCK)
index 3a3c851..9e0e60c 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_syscalls.c 4.45    83/03/23        */
+/*     uipc_syscalls.c 4.46    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
-#include "../h/descrip.h"
 #include "../h/uio.h"
 
 /*
  * System call interface to the socket abstraction.
  */
 
 #include "../h/uio.h"
 
 /*
  * System call interface to the socket abstraction.
  */
 
+struct file *getsock();
+extern struct fileops socketops;
+
 socket()
 {
        register struct a {
 socket()
 {
        register struct a {
@@ -33,10 +35,11 @@ socket()
                return;
        fp->f_flag = FREAD|FWRITE;
        fp->f_type = DTYPE_SOCKET;
                return;
        fp->f_flag = FREAD|FWRITE;
        fp->f_type = DTYPE_SOCKET;
+       fp->f_ops = &socketops;
        u.u_error = socreate(uap->domain, &so, uap->type, uap->protocol);
        if (u.u_error)
                goto bad;
        u.u_error = socreate(uap->domain, &so, uap->type, uap->protocol);
        if (u.u_error)
                goto bad;
-       fp->f_socket = so;
+       fp->f_data = (caddr_t)so;
        return;
 bad:
        u.u_ofile[u.u_r.r_val1] = 0;
        return;
 bad:
        u.u_ofile[u.u_r.r_val1] = 0;
@@ -53,17 +56,13 @@ bind()
        register struct file *fp;
        struct mbuf *nam;
 
        register struct file *fp;
        struct mbuf *nam;
 
-       fp = getf(uap->s);
+       fp = getsock(uap->s);
        if (fp == 0)
                return;
        if (fp == 0)
                return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
-       u.u_error = sockname(&nam, uap->name, uap->namelen);
+       u.u_error = sockargs(&nam, uap->name, uap->namelen);
        if (u.u_error)
                return;
        if (u.u_error)
                return;
-       u.u_error = sobind(fp->f_socket, nam);
+       u.u_error = sobind((struct socket *)fp->f_data, nam);
        m_freem(nam);
 }
 
        m_freem(nam);
 }
 
@@ -75,14 +74,10 @@ listen()
        } *uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        } *uap = (struct a *)u.u_ap;
        register struct file *fp;
 
-       fp = getf(uap->s);
+       fp = getsock(uap->s);
        if (fp == 0)
                return;
        if (fp == 0)
                return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
-       u.u_error = solisten(fp->f_socket, uap->backlog);
+       u.u_error = solisten((struct socket *)fp->f_data, uap->backlog);
 }
 
 accept()
 }
 
 accept()
@@ -109,15 +104,11 @@ accept()
                return;
        }
 noname:
                return;
        }
 noname:
-       fp = getf(uap->s);
+       fp = getsock(uap->s);
        if (fp == 0)
                return;
        if (fp == 0)
                return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
        s = splnet();
        s = splnet();
-       so = fp->f_socket;
+       so = (struct socket *)fp->f_data;
        if ((so->so_options & SO_ACCEPTCONN) == 0) {
                u.u_error = EINVAL;
                splx(s);
        if ((so->so_options & SO_ACCEPTCONN) == 0) {
                u.u_error = EINVAL;
                splx(s);
@@ -140,16 +131,7 @@ noname:
                splx(s);
                return;
        }
                splx(s);
                return;
        }
-       if ((so->so_options & SO_NEWFDONCONN) == 0) {
-               struct socket *nso = so->so_q;
-               (void) soqremque(nso, 1);
-               u.u_error = soclose(so, 1);
-               fp->f_socket = nso;
-               nso->so_q = 0;
-               so = nso;
-               goto ret;
-       }
-       if (ufalloc() < 0) {
+       if (ufalloc(0) < 0) {
                splx(s);
                return;
        }
                splx(s);
                return;
        }
@@ -166,8 +148,8 @@ noname:
        }
        fp->f_type = DTYPE_SOCKET;
        fp->f_flag = FREAD|FWRITE;
        }
        fp->f_type = DTYPE_SOCKET;
        fp->f_flag = FREAD|FWRITE;
-       fp->f_socket = so;
-ret:
+       fp->f_ops = &socketops;
+       fp->f_data = (caddr_t)so;
        nam = m_get(M_WAIT, MT_SONAME);
        (void) soaccept(so, nam);
        if (uap->name) {
        nam = m_get(M_WAIT, MT_SONAME);
        (void) soaccept(so, nam);
        if (uap->name) {
@@ -195,15 +177,11 @@ connect()
        struct mbuf *nam;
        int s;
 
        struct mbuf *nam;
        int s;
 
-       fp = getf(uap->s);
+       fp = getsock(uap->s);
        if (fp == 0)
                return;
        if (fp == 0)
                return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
-       so = fp->f_socket;
-       u.u_error = sockname(&nam, uap->name, uap->namelen);
+       so = (struct socket *)fp->f_data;
+       u.u_error = sockargs(&nam, uap->name, uap->namelen);
        if (u.u_error)
                return;
        u.u_error = soconnect(so, nam);
        if (u.u_error)
                return;
        u.u_error = soconnect(so, nam);
@@ -213,13 +191,18 @@ connect()
        if ((so->so_state & SS_NBIO) &&
            (so->so_state & SS_ISCONNECTING)) {
                u.u_error = EINPROGRESS;
        if ((so->so_state & SS_NBIO) &&
            (so->so_state & SS_ISCONNECTING)) {
                u.u_error = EINPROGRESS;
-               splx(s);
-               goto bad;
+               goto bad2;
+       }
+       if (setjmp(&u.u_qsave)) {
+               if (u.u_error == 0)
+                       u.u_error = EINTR;
+               goto bad2;
        }
        while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
                sleep((caddr_t)&so->so_timeo, PZERO+1);
        u.u_error = so->so_error;
        so->so_error = 0;
        }
        while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
                sleep((caddr_t)&so->so_timeo, PZERO+1);
        u.u_error = so->so_error;
        so->so_error = 0;
+bad2:
        splx(s);
 bad:
        m_freem(nam);
        splx(s);
 bad:
        m_freem(nam);
@@ -241,35 +224,18 @@ sendto()
                caddr_t to;
                int     tolen;
        } *uap = (struct a *)u.u_ap;
                caddr_t to;
                int     tolen;
        } *uap = (struct a *)u.u_ap;
-       register struct file *fp;
-       struct uio auio;
+       struct msghdr msg;
        struct iovec aiov;
        struct iovec aiov;
-       struct mbuf *to;
 
 
-       fp = getf(uap->s);
-       if (fp == 0)
-               return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
-       auio.uio_iov = &aiov;
-       auio.uio_iovcnt = 1;
+       msg.msg_name = uap->to;
+       msg.msg_namelen = uap->tolen;
+       msg.msg_iov = &aiov;
+       msg.msg_iovlen = 1;
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->len;
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->len;
-       auio.uio_resid = uap->len;
-       auio.uio_segflg = 0;
-       auio.uio_offset = 0;    /* XXX */
-       if (useracc(uap->buf, (u_int)uap->len, B_READ) == 0) {
-               u.u_error = EFAULT;
-               return;
-       }
-       u.u_error = sockname(&to, uap->to, uap->tolen);
-       if (u.u_error)
-               return;
-       u.u_error = sosend(fp->f_socket, to, &auio, uap->flags);
-       u.u_r.r_val1 = uap->len - auio.uio_resid;
-       m_freem(to);
+       msg.msg_accrights = 0;
+       msg.msg_accrightslen = 0;
+       sendit(uap->s, &msg, uap->flags);
 }
 
 send()
 }
 
 send()
@@ -280,32 +246,107 @@ send()
                int     len;
                int     flags;
        } *uap = (struct a *)u.u_ap;
                int     len;
                int     flags;
        } *uap = (struct a *)u.u_ap;
-       register struct file *fp;
-       struct uio auio;
+       struct msghdr msg;
        struct iovec aiov;
 
        struct iovec aiov;
 
-       fp = getf(uap->s);
-       if (fp == 0)
-               return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
-       auio.uio_iov = &aiov;
-       auio.uio_iovcnt = 1;
+       msg.msg_name = 0;
+       msg.msg_namelen = 0;
+       msg.msg_iov = &aiov;
+       msg.msg_iovlen = 1;
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->len;
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->len;
-       auio.uio_resid = uap->len;
-       auio.uio_segflg = 0;
-       auio.uio_offset = 0;    /* XXX */
-       if (useracc(uap->buf, (u_int)uap->len, B_READ) == 0) {
-               u.u_error = EFAULT;
+       msg.msg_accrights = 0;
+       msg.msg_accrightslen = 0;
+       sendit(uap->s, &msg, uap->flags);
+}
+
+sendmsg()
+{
+       register struct a {
+               int     s;
+               caddr_t msg;
+               int     flags;
+       } *uap = (struct a *)u.u_ap;
+       struct msghdr msg;
+       struct iovec aiov[MSG_MAXIOVLEN];
+
+       u.u_error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg));
+       if (u.u_error)
+               return;
+       if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0])) {
+               u.u_error = EMSGSIZE;
                return;
        }
                return;
        }
+       u.u_error =
+           copyin((caddr_t)msg.msg_iov, (caddr_t)aiov,
+               (unsigned)(msg.msg_iovlen * sizeof (aiov[0])));
        if (u.u_error)
                return;
        if (u.u_error)
                return;
-       u.u_error = sosend(fp->f_socket, (struct mbuf *)0, &auio, uap->flags);
-       u.u_r.r_val1 = uap->len - auio.uio_resid;
+       msg.msg_iov = aiov;
+#ifdef notdef
+printf("sendmsg name %x namelen %d iov %x iovlen %d accrights %x &len %d\n",
+msg.msg_name, msg.msg_namelen, msg.msg_iov, msg.msg_iovlen,
+msg.msg_accrights, msg.msg_accrightslen);
+#endif
+       sendit(uap->s, &msg, uap->flags);
+}
+
+sendit(s, mp, flags)
+       int s;
+       register struct msghdr *mp;
+       int flags;
+{
+       register struct file *fp;
+       struct uio auio;
+       register struct iovec *iov;
+       register int i;
+       struct mbuf *to, *rights;
+       int len;
+       
+       fp = getsock(s);
+       if (fp == 0)
+               return;
+       auio.uio_iov = mp->msg_iov;
+       auio.uio_iovcnt = mp->msg_iovlen;
+       auio.uio_segflg = 0;
+       auio.uio_offset = 0;                    /* XXX */
+       auio.uio_resid = 0;
+       iov = mp->msg_iov;
+       for (i = 0; i < mp->msg_iovlen; i++) {
+               if (iov->iov_len < 0) {
+                       u.u_error = EINVAL;
+                       return;
+               }
+               if (useracc(iov->iov_base, (u_int)iov->iov_len, B_READ) == 0) {
+                       u.u_error = EFAULT;
+                       return;
+               }
+               auio.uio_resid += iov->iov_len;
+               iov++;
+       }
+       if (mp->msg_name) {
+               u.u_error =
+                   sockargs(&to, mp->msg_name, mp->msg_namelen);
+               if (u.u_error)
+                       return;
+       } else
+               to = 0;
+       if (mp->msg_accrights) {
+               u.u_error =
+                   sockargs(&rights, mp->msg_accrights, mp->msg_accrightslen);
+               if (u.u_error)
+                       goto bad;
+       } else
+               rights = 0;
+       len = auio.uio_resid;
+       u.u_error =
+           sosend((struct socket *)fp->f_data, to, &auio, flags, rights);
+       u.u_r.r_val1 = len - auio.uio_resid;
+       if (rights)
+               m_freem(rights);
+bad:
+       if (to)
+               m_freem(to);
 }
 
 recvfrom()
 }
 
 recvfrom()
@@ -318,56 +359,23 @@ recvfrom()
                caddr_t from;
                int     *fromlenaddr;
        } *uap = (struct a *)u.u_ap;
                caddr_t from;
                int     *fromlenaddr;
        } *uap = (struct a *)u.u_ap;
-       register struct file *fp;
-       struct uio auio;
+       struct msghdr msg;
        struct iovec aiov;
        struct iovec aiov;
-       struct mbuf *from;
-       int fromlen;
+       int len;
 
 
-       u.u_error = copyin((caddr_t)uap->fromlenaddr, (caddr_t)&fromlen,
-               sizeof (fromlen));
+       u.u_error = copyin((caddr_t)uap->fromlenaddr, (caddr_t)&len,
+          sizeof (len));
        if (u.u_error)
                return;
        if (u.u_error)
                return;
-       fp = getf(uap->s);
-       if (fp == 0)
-               return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
-       auio.uio_iov = &aiov;
-       auio.uio_iovcnt = 1;
+       msg.msg_name = uap->from;
+       msg.msg_namelen = len;
+       msg.msg_iov = &aiov;
+       msg.msg_iovlen = 1;
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->len;
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->len;
-       auio.uio_resid = uap->len;
-       auio.uio_segflg = 0;
-       auio.uio_offset = 0;    /* XXX */
-       if (useracc(uap->buf, (u_int)uap->len, B_WRITE) == 0)  {
-               u.u_error = EFAULT;
-               return;
-       }
-       from = 0;
-       u.u_error = soreceive(fp->f_socket, &from, &auio, uap->flags);
-       if (u.u_error)
-               goto bad;
-       if (from == 0)
-               fromlen = 0;
-       else {
-               if (fromlen > from->m_len)
-                       fromlen = from->m_len;
-               u.u_error = copyout(mtod(from, caddr_t), uap->from,
-                       (u_int)fromlen);
-               if (u.u_error)
-                       goto bad;
-       }
-       u.u_error = copyout((caddr_t)&fromlen, (caddr_t)uap->fromlenaddr,
-           sizeof (fromlen));
-       if (u.u_error)
-               goto bad;
-       u.u_r.r_val1 = uap->len - auio.uio_resid;
-bad:
-       if (from)
-               m_freem(from);
+       msg.msg_accrights = 0;
+       msg.msg_accrightslen = 0;
+       recvit(uap->s, &msg, uap->flags, (caddr_t)uap->fromlenaddr, (caddr_t)0);
 }
 
 recv()
 }
 
 recv()
@@ -378,43 +386,121 @@ recv()
                int     len;
                int     flags;
        } *uap = (struct a *)u.u_ap;
                int     len;
                int     flags;
        } *uap = (struct a *)u.u_ap;
-       register struct file *fp;
-       struct uio auio;
+       struct msghdr msg;
        struct iovec aiov;
 
        struct iovec aiov;
 
-       fp = getf(uap->s);
-       if (fp == 0)
-               return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
-       auio.uio_iov = &aiov;
-       auio.uio_iovcnt = 1;
+       msg.msg_name = 0;
+       msg.msg_namelen = 0;
+       msg.msg_iov = &aiov;
+       msg.msg_iovlen = 1;
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->len;
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->len;
-       auio.uio_resid = uap->len;
-       auio.uio_segflg = 0;
-       auio.uio_offset = 0;    /* XXX */
-       if (useracc(uap->buf, (u_int)uap->len, B_WRITE) == 0)  {
-               u.u_error = EFAULT;
-               return;
-       }
-       u.u_error =
-           soreceive(fp->f_socket, (struct mbuf **)0, &auio, uap->flags);
-       u.u_r.r_val1 = uap->len - auio.uio_resid;
+       msg.msg_accrights = 0;
+       msg.msg_accrightslen = 0;
+       recvit(uap->s, &msg, uap->flags, (caddr_t)0, (caddr_t)0);
 }
 
 }
 
-sendmsg()
+recvmsg()
 {
 {
+       register struct a {
+               int     s;
+               struct  msghdr *msg;
+               int     flags;
+       } *uap = (struct a *)u.u_ap;
+       struct msghdr msg;
+       struct iovec aiov[MSG_MAXIOVLEN];
 
 
-       u.u_error = EINVAL;
+       u.u_error = copyin((caddr_t)uap->msg, (caddr_t)&msg, sizeof (msg));
+       if (u.u_error)
+               return;
+       if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0])) {
+               u.u_error = EMSGSIZE;
+               return;
+       }
+       u.u_error =
+           copyin((caddr_t)msg.msg_iov, (caddr_t)aiov,
+               (unsigned)(msg.msg_iovlen * sizeof (aiov[0])));
+       if (u.u_error)
+               return;
+       msg.msg_iov = aiov;
+       if (msg.msg_accrights)
+               if (useracc((caddr_t)msg.msg_accrights,
+                   (unsigned)msg.msg_accrightslen, B_WRITE) == 0) {
+                       u.u_error = EFAULT;
+                       return;
+               }
+       recvit(uap->s, &msg, uap->flags,
+           (caddr_t)&uap->msg->msg_namelen,
+           (caddr_t)&uap->msg->msg_accrightslen);
 }
 
 }
 
-recvmsg()
+recvit(s, mp, flags, namelenp, rightslenp)
+       int s;
+       register struct msghdr *mp;
+       int flags;
+       caddr_t namelenp, rightslenp;
 {
 {
-
-       u.u_error = EINVAL;
+       register struct file *fp;
+       struct uio auio;
+       register struct iovec *iov;
+       register int i;
+       struct mbuf *from, *rights;
+       int len;
+       
+       fp = getsock(s);
+       if (fp == 0)
+               return;
+       auio.uio_iov = mp->msg_iov;
+       auio.uio_iovcnt = mp->msg_iovlen;
+       auio.uio_segflg = 0;
+       auio.uio_offset = 0;                    /* XXX */
+       auio.uio_resid = 0;
+       iov = mp->msg_iov;
+       for (i = 0; i < mp->msg_iovlen; i++) {
+               if (iov->iov_len < 0) {
+                       u.u_error = EINVAL;
+                       return;
+               }
+               if (useracc(iov->iov_base, (u_int)iov->iov_len, B_WRITE) == 0) {
+                       u.u_error = EFAULT;
+                       return;
+               }
+               auio.uio_resid += iov->iov_len;
+               iov++;
+       }
+       len = auio.uio_resid;
+       u.u_error =
+           soreceive((struct socket *)fp->f_data, &from, &auio,
+               flags, &rights);
+       u.u_r.r_val1 = len - auio.uio_resid;
+       if (mp->msg_name) {
+               len = mp->msg_namelen;
+               if (len <= 0 || from == 0)
+                       len = 0;
+               else {
+                       if (len > from->m_len)
+                               len = from->m_len;
+                       (void) copyout((caddr_t)mtod(from, caddr_t),
+                           (caddr_t)mp->msg_name, (unsigned)len);
+               }
+               (void) copyout((caddr_t)&len, namelenp, sizeof (int));
+       }
+       if (mp->msg_accrights) {
+               len = mp->msg_accrightslen;
+               if (len <= 0 || rights == 0)
+                       len = 0;
+               else {
+                       if (len > rights->m_len)
+                               len = rights->m_len;
+                       (void) copyout((caddr_t)mtod(rights, caddr_t),
+                           (caddr_t)mp->msg_accrights, (unsigned)len);
+               }
+               (void) copyout((caddr_t)&len, rightslenp, sizeof (int));
+       }
+       if (rights)
+               m_freem(rights);
+       if (from)
+               m_freem(from);
 }
 
 shutdown()
 }
 
 shutdown()
@@ -425,14 +511,10 @@ shutdown()
        } *uap = (struct a *)u.u_ap;
        struct file *fp;
 
        } *uap = (struct a *)u.u_ap;
        struct file *fp;
 
-       fp = getf(uap->s);
+       fp = getsock(uap->s);
        if (fp == 0)
                return;
        if (fp == 0)
                return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
-       u.u_error = soshutdown(fp->f_socket, uap->how);
+       u.u_error = soshutdown((struct socket *)fp->f_data, uap->how);
 }
 
 setsockopt()
 }
 
 setsockopt()
@@ -447,13 +529,9 @@ setsockopt()
        struct file *fp;
        struct mbuf *m = NULL;
 
        struct file *fp;
        struct mbuf *m = NULL;
 
-       fp = getf(uap->s);
+       fp = getsock(uap->s);
        if (fp == 0)
                return;
        if (fp == 0)
                return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
        if (uap->valsize > MLEN) {
                u.u_error = EINVAL;
                return;
        if (uap->valsize > MLEN) {
                u.u_error = EINVAL;
                return;
@@ -464,13 +542,14 @@ setsockopt()
                        u.u_error = ENOBUFS;
                        return;
                }
                        u.u_error = ENOBUFS;
                        return;
                }
-               u.u_error = copyin(uap->val, mtod(m, caddr_t),
-                 (u_int)uap->valsize);
+               u.u_error =
+                   copyin(uap->val, mtod(m, caddr_t), (u_int)uap->valsize);
                if (u.u_error)
                        goto bad;
                m->m_len = uap->valsize;
        }
                if (u.u_error)
                        goto bad;
                m->m_len = uap->valsize;
        }
-       u.u_error = sosetopt(fp->f_socket, uap->level, uap->name, m);
+       u.u_error =
+           sosetopt((struct socket *)fp->f_data, uap->level, uap->name, m);
 bad:
        if (m != NULL)
                (void) m_free(m);
 bad:
        if (m != NULL)
                (void) m_free(m);
@@ -489,13 +568,9 @@ getsockopt()
        struct mbuf *m = NULL;
        int valsize;
 
        struct mbuf *m = NULL;
        int valsize;
 
-       fp = getf(uap->s);
+       fp = getsock(uap->s);
        if (fp == 0)
                return;
        if (fp == 0)
                return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
        if (uap->val) {
                u.u_error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
                        sizeof (valsize));
        if (uap->val) {
                u.u_error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
                        sizeof (valsize));
@@ -507,7 +582,8 @@ getsockopt()
                        return;
                }
        }
                        return;
                }
        }
-       u.u_error = sogetopt(fp->f_socket, uap->level, uap->name, m);
+       u.u_error =
+           sogetopt((struct socket *)fp->f_data, uap->level, uap->name, m);
        if (u.u_error)
                goto bad;
        if (uap->val) {
        if (u.u_error)
                goto bad;
        if (uap->val) {
@@ -530,12 +606,10 @@ pipe()
        struct socket *rso, *wso;
        int r;
 
        struct socket *rso, *wso;
        int r;
 
-       u.u_error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0,
-               (struct socketopt *)0);
+       u.u_error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0);
        if (u.u_error)
                return;
        if (u.u_error)
                return;
-       u.u_error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0,
-               (struct socketopt *)0);
+       u.u_error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0);
        if (u.u_error)
                goto free;
        rf = falloc();
        if (u.u_error)
                goto free;
        rf = falloc();
@@ -544,13 +618,15 @@ pipe()
        r = u.u_r.r_val1;
        rf->f_flag = FREAD;
        rf->f_type = DTYPE_SOCKET;
        r = u.u_r.r_val1;
        rf->f_flag = FREAD;
        rf->f_type = DTYPE_SOCKET;
-       rf->f_socket = rso;
+       rf->f_ops = &socketops;
+       rf->f_data = (caddr_t)rso;
        wf = falloc();
        if (wf == NULL)
                goto free3;
        wf->f_flag = FWRITE;
        wf->f_type = DTYPE_SOCKET;
        wf = falloc();
        if (wf == NULL)
                goto free3;
        wf->f_flag = FWRITE;
        wf->f_type = DTYPE_SOCKET;
-       wf->f_socket = wso;
+       wf->f_ops = &socketops;
+       wf->f_data = (caddr_t)wso;
        u.u_r.r_val2 = u.u_r.r_val1;
        u.u_r.r_val1 = r;
        if (piconnect(wso, rso) == 0)
        u.u_r.r_val2 = u.u_r.r_val1;
        u.u_r.r_val1 = r;
        if (piconnect(wso, rso) == 0)
@@ -585,17 +661,13 @@ getsockname()
        struct mbuf *m;
        int len;
 
        struct mbuf *m;
        int len;
 
-       fp = getf(uap->fdes);
+       fp = getsock(uap->fdes);
        if (fp == 0)
                return;
        if (fp == 0)
                return;
-       if (fp->f_type != DTYPE_SOCKET) {
-               u.u_error = ENOTSOCK;
-               return;
-       }
        u.u_error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len));
        if (u.u_error)
                return;
        u.u_error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len));
        if (u.u_error)
                return;
-       so = fp->f_socket;
+       so = (struct socket *)fp->f_data;
        m = m_getclr(M_WAIT, MT_SONAME);
        if (m == NULL) {
                u.u_error = ENOBUFS;
        m = m_getclr(M_WAIT, MT_SONAME);
        if (m == NULL) {
                u.u_error = ENOBUFS;
@@ -614,7 +686,7 @@ bad:
        m_freem(m);
 }
 
        m_freem(m);
 }
 
-sockname(aname, name, namelen)
+sockargs(aname, name, namelen)
        struct mbuf **aname;
        caddr_t name;
        int namelen;
        struct mbuf **aname;
        caddr_t name;
        int namelen;
@@ -635,3 +707,19 @@ sockname(aname, name, namelen)
                *aname = m;
        return (error);
 }
                *aname = m;
        return (error);
 }
+
+struct file *
+getsock(fdes)
+       int fdes;
+{
+       register struct file *fp;
+
+       fp = getf(fdes);
+       if (fp == NULL)
+               return (0);
+       if (fp->f_type != DTYPE_SOCKET) {
+               u.u_error = ENOTSOCK;
+               return (0);
+       }
+       return (fp);
+}
index 957a3e7..633a882 100644 (file)
@@ -1,4 +1,4 @@
-/*     uipc_usrreq.c   1.9     83/04/03        */
+/*     uipc_usrreq.c   1.10    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/dir.h"
 
 #include "../h/param.h"
 #include "../h/dir.h"
 #include "../h/un.h"
 #include "../h/inode.h"
 #include "../h/nami.h"
 #include "../h/un.h"
 #include "../h/inode.h"
 #include "../h/nami.h"
+#include "../h/file.h"
 
 /*
  * Unix communications domain.
 
 /*
  * Unix communications domain.
+ *
+ * TODO:
+ *     SEQPACKET, RDM
+ *     change for names in file system
+ *     need a proper out-of-band
  */
 
 /*ARGSUSED*/
  */
 
 /*ARGSUSED*/
-uipc_usrreq(so, req, m, nam)
+uipc_usrreq(so, req, m, nam, rights)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m, *nam;
+       struct mbuf *m, *nam, *rights;
 {
        struct unpcb *unp = sotounpcb(so);
        register struct socket *so2;
        int error = 0;
 
 {
        struct unpcb *unp = sotounpcb(so);
        register struct socket *so2;
        int error = 0;
 
-       if (unp == 0 && req != PRU_ATTACH)
-               return (EINVAL);                        /* XXX */
+       if (req != PRU_SEND && rights && rights->m_len) {
+               error = EOPNOTSUPP;
+               goto release;
+       }
+       if (unp == 0 && req != PRU_ATTACH) {
+               error = EINVAL;
+               goto release;
+       }
        switch (req) {
 
        case PRU_ATTACH:
        switch (req) {
 
        case PRU_ATTACH:
@@ -55,6 +67,12 @@ uipc_usrreq(so, req, m, nam)
                error = unp_connect(so, nam);
                break;
 
                error = unp_connect(so, nam);
                break;
 
+#ifdef notdef
+       case PRU_CONNECT2:
+               error = unp_connect2(so, (struct mbuf *)0, (struct socket *)nam);
+               break;
+
+#endif
        case PRU_DISCONNECT:
                unp_disconnect(unp);
                break;
        case PRU_DISCONNECT:
                unp_disconnect(unp);
                break;
@@ -121,9 +139,18 @@ uipc_usrreq(so, req, m, nam)
                        }
                        so2 = unp->unp_conn->unp_socket;
                        /* BEGIN XXX */
                        }
                        so2 = unp->unp_conn->unp_socket;
                        /* BEGIN XXX */
-                       if (sbspace(&so2->so_rcv) > 0)
+                       if (rights) {
+                               error = unp_internalize(rights);
+                               if (error)
+                                       break;
+                       }
+                       if (sbspace(&so2->so_rcv) > 0) {
                                (void) sbappendaddr(&so2->so_rcv,
                                (void) sbappendaddr(&so2->so_rcv,
-                                       mtod(nam, struct sockaddr *), m);
+                                   mtod(nam, struct sockaddr *), m,
+                                   rights);
+                               sbwakeup(&so2->so_rcv);
+                               m = 0;
+                       }
                        /* END XXX */
                        if (nam)
                                unp_disconnect(unp);
                        /* END XXX */
                        if (nam)
                                unp_disconnect(unp);
@@ -132,6 +159,10 @@ uipc_usrreq(so, req, m, nam)
                case SOCK_STREAM:
 #define        rcv (&so2->so_rcv)
 #define        snd (&so->so_snd)
                case SOCK_STREAM:
 #define        rcv (&so2->so_rcv)
 #define        snd (&so->so_snd)
+                       if (rights && rights->m_len) {
+                               error = EOPNOTSUPP;
+                               break;
+                       }
                        if (unp->unp_conn == 0)
                                panic("uipc 3");
                        so2 = unp->unp_conn->unp_socket;
                        if (unp->unp_conn == 0)
                                panic("uipc 3");
                        so2 = unp->unp_conn->unp_socket;
@@ -153,6 +184,7 @@ uipc_usrreq(so, req, m, nam)
                default:
                        panic("uipc 4");
                }
                default:
                        panic("uipc 4");
                }
+               m = 0;
                break;
 
        case PRU_ABORT:
                break;
 
        case PRU_ABORT:
@@ -184,9 +216,13 @@ uipc_usrreq(so, req, m, nam)
        default:
                panic("piusrreq");
        }
        default:
                panic("piusrreq");
        }
+release:
+       if (m)
+               m_freem(m);
        return (error);
 }
 
        return (error);
 }
 
+/* SHOULD BE PIPSIZ and 0 */
 int    unp_sendspace = 1024*2;
 int    unp_recvspace = 1024*2;
 
 int    unp_sendspace = 1024*2;
 int    unp_recvspace = 1024*2;
 
@@ -237,7 +273,10 @@ unp_bind(unp, nam)
        int error;
 
        u.u_dirp = soun->sun_path;
        int error;
 
        u.u_dirp = soun->sun_path;
-       soun->sun_path[sizeof(soun->sun_path)-1] = 0;
+       if (nam->m_len == MLEN)
+               return (EINVAL);
+       *(mtod(nam, caddr_t) + nam->m_len) = 0;
+/* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */
        ip = namei(schar, CREATE, 1);
        if (ip) {
                iput(ip);
        ip = namei(schar, CREATE, 1);
        if (ip) {
                iput(ip);
@@ -264,14 +303,14 @@ unp_connect(so, nam)
        struct mbuf *nam;
 {
        register struct sockaddr_un *soun = mtod(nam, struct sockaddr_un *);
        struct mbuf *nam;
 {
        register struct sockaddr_un *soun = mtod(nam, struct sockaddr_un *);
-       struct unpcb *unp = sotounpcb(so);
        register struct inode *ip;
        int error;
        register struct inode *ip;
        int error;
-       struct socket *so2;
-       struct unpcb *unp2;
+       register struct socket *so2;
 
        u.u_dirp = soun->sun_path;
 
        u.u_dirp = soun->sun_path;
-       soun->sun_path[sizeof(soun->sun_path)-1] = 0;
+       if (nam->m_len + (nam->m_off - MMINOFF) == MLEN)
+               return (EMSGSIZE);
+       *(mtod(nam, caddr_t) + nam->m_len) = 0;
        ip = namei(schar, LOOKUP, 1);
        if (ip == 0) {
                error = u.u_error;
        ip = namei(schar, LOOKUP, 1);
        if (ip == 0) {
                error = u.u_error;
@@ -287,41 +326,48 @@ unp_connect(so, nam)
                error = ECONNREFUSED;
                goto bad;
        }
                error = ECONNREFUSED;
                goto bad;
        }
-       if (so2->so_type != so->so_type) {
-               error = EPROTOTYPE;
-               goto bad;
-       }
+       error = unp_connect2(so, nam, so2);
+bad:
+       iput(ip);
+       return (error);
+}
+
+unp_connect2(so, sonam, so2)
+       register struct socket *so;
+       struct mbuf *sonam;
+       register struct socket *so2;
+{
+       register struct unpcb *unp = sotounpcb(so);
+       register struct unpcb *unp2;
+
+       if (so2->so_type != so->so_type)
+               return (EPROTOTYPE);
        switch (so->so_type) {
 
        case SOCK_DGRAM:
        switch (so->so_type) {
 
        case SOCK_DGRAM:
-               unp->unp_conn = sotounpcb(so2);
                unp2 = sotounpcb(so2);
                unp2 = sotounpcb(so2);
+               unp->unp_conn = unp2;
                unp->unp_nextref = unp2->unp_refs;
                unp2->unp_refs = unp;
                break;
 
        case SOCK_STREAM:
                if ((so2->so_options&SO_ACCEPTCONN) == 0 ||
                unp->unp_nextref = unp2->unp_refs;
                unp2->unp_refs = unp;
                break;
 
        case SOCK_STREAM:
                if ((so2->so_options&SO_ACCEPTCONN) == 0 ||
-                   (so2 = sonewconn(so2)) == 0) {
-                       error = ECONNREFUSED;
-                       goto bad;
-               }
+                   (so2 = sonewconn(so2)) == 0)
+                       return (ECONNREFUSED);
                unp2 = sotounpcb(so2);
                unp->unp_conn = unp2;
                unp2->unp_conn = unp;
                unp2 = sotounpcb(so2);
                unp->unp_conn = unp2;
                unp2->unp_conn = unp;
-               unp2->unp_remaddr = m_copy(nam, 0, (int)M_COPYALL);
+               if (sonam)
+                       unp2->unp_remaddr = m_copy(sonam, 0, (int)M_COPYALL);
                break;
 
        default:
                break;
 
        default:
-               panic("uipc connip");
+               panic("unp_connect2");
        }
        soisconnected(so2);
        soisconnected(so);
        }
        soisconnected(so2);
        soisconnected(so);
-       iput(ip);
        return (0);
        return (0);
-bad:
-       iput(ip);
-       return (error);
 }
 
 unp_disconnect(unp)
 }
 
 unp_disconnect(unp)
@@ -359,12 +405,14 @@ unp_disconnect(unp)
        }
 }
 
        }
 }
 
+#ifdef notdef
 unp_abort(unp)
        struct unpcb *unp;
 {
 
        unp_detach(unp);
 }
 unp_abort(unp)
        struct unpcb *unp;
 {
 
        unp_detach(unp);
 }
+#endif
 
 /*ARGSUSED*/
 unp_usrclosed(unp)
 
 /*ARGSUSED*/
 unp_usrclosed(unp)
@@ -382,7 +430,162 @@ unp_drop(unp, errno)
        unp_disconnect(unp);
 }
 
        unp_disconnect(unp);
 }
 
+#ifdef notdef
 unp_drain()
 {
 
 }
 unp_drain()
 {
 
 }
+#endif
+
+unp_externalize(rights)
+       struct mbuf *rights;
+{
+       int newfds = rights->m_len / sizeof (int);
+       register int i;
+       register struct file **rp = mtod(rights, struct file **);
+       register struct file *fp;
+       int f;
+
+       if (newfds > ufavail()) {
+               for (i = 0; i < newfds; i++) {
+                       fp = *rp;
+                       unp_discard(fp);
+                       *rp++ = 0;
+               }
+               return (EMSGSIZE);
+       }
+       for (i = 0; i < newfds; i++) {
+               f = ufalloc(0);
+               if (f < 0)
+                       panic("unp_externalize");
+               fp = *rp;
+               u.u_ofile[f] = fp;
+               fp->f_msgcount--;
+               *(int *)rp = f;
+       }
+       return (0);
+}
+
+unp_internalize(rights)
+       struct mbuf *rights;
+{
+       register struct file **rp;
+       int oldfds = rights->m_len / sizeof (int);
+       register int i;
+       register struct file *fp;
+
+       rp = mtod(rights, struct file **);
+       for (i = 0; i < oldfds; i++) {
+               if (getf(*(int *)rp++) == 0)
+                       return (EBADF);
+       rp = mtod(rights, struct file **);
+       for (i = 0; i < oldfds; i++)
+               fp = getf(*(int *)rp);
+               *rp++ = fp;
+               fp->f_count++;
+               fp->f_msgcount++;
+       }
+       return (0);
+}
+
+int    unp_defer, unp_gcing;
+int    unp_mark();
+
+unp_gc()
+{
+       register struct file *fp;
+       register struct socket *so;
+
+       if (unp_gcing)
+               return;
+       unp_gcing = 1;
+restart:
+       unp_defer = 0;
+       for (fp = file; fp < fileNFILE; fp++)
+               fp->f_flag &= ~(FMARK|FDEFER);
+       do {
+               for (fp = file; fp < fileNFILE; fp++) {
+                       if (fp->f_count == 0)
+                               continue;
+                       if (fp->f_flag & FDEFER) {
+                               fp->f_flag &= ~FDEFER;
+                               unp_defer--;
+                       } else {
+                               if (fp->f_flag & FMARK)
+                                       continue;
+                               if (fp->f_count == fp->f_msgcount)
+                                       continue;
+                               fp->f_flag |= FMARK;
+                       }
+                       if (fp->f_type != DTYPE_SOCKET)
+                               continue;
+                       so = (struct socket *)fp->f_data;
+                       if (so->so_proto->pr_family != AF_UNIX ||
+                           (so->so_proto->pr_flags&PR_ADDR) == 0)
+                               continue;
+                       if (so->so_rcv.sb_flags & SB_LOCK) {
+                               sbwait(&so->so_rcv);
+                               goto restart;
+                       }
+                       unp_scan(so->so_rcv.sb_mb, unp_mark);
+               }
+       } while (unp_defer);
+       for (fp = file; fp < fileNFILE; fp++) {
+               if (fp->f_count == 0)
+                       continue;
+               if (fp->f_count == fp->f_msgcount && (fp->f_flag&FMARK)==0) {
+                       if (fp->f_type != DTYPE_SOCKET)
+                               panic("unp_gc");
+                       (void) soshutdown((struct socket *)fp->f_data, 0);
+               }
+       }
+       unp_gcing = 0;
+}
+
+unp_scan(m, op)
+       register struct mbuf *m;
+       int (*op)();
+{
+       register struct file **rp;
+       register int i;
+       int qfds;
+
+       while (m) {
+               m = m->m_next;
+               if (m == 0)
+                       goto bad;
+               if (m->m_len) {
+                       qfds = m->m_len / sizeof (struct file *);
+                       rp = mtod(m, struct file **);
+                       for (i = 0; i < qfds; i++)
+                               (*op)(*rp++);
+               }
+               do {
+                       m = m->m_next;
+                       if (m == 0)
+                               goto bad;
+               } while (m->m_act == 0);
+               m = m->m_next;
+       }
+       return;
+bad:
+       panic("unp_gcscan");
+}
+
+unp_mark(fp)
+       struct file *fp;
+{
+
+       if (fp->f_flag & FMARK)
+               return;
+       unp_defer++;
+       fp->f_flag |= (FMARK|FDEFER);
+}
+
+unp_discard(fp)
+       struct file *fp;
+{
+
+       fp->f_msgcount--;
+       closef(fp, 0);
+}
index 7d71b2d..fecc165 100644 (file)
@@ -1,4 +1,4 @@
-/*     vfs_syscalls.c  4.56    83/05/21        */
+/*     vfs_syscalls.c  4.57    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
-#include "../h/descrip.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
+#include "../h/mount.h"
+
+extern struct fileops inodeops;
+struct file *getinode();
 
 /*
  * Change current working directory (``.'').
 
 /*
  * Change current working directory (``.'').
@@ -72,76 +75,74 @@ bad:
  */
 open()
 {
  */
 open()
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                char    *fname;
-               int     flags;
                int     mode;
                int     mode;
-       } *uap;
-       int checkpermissions = 1, flags;
+               int     crtmode;
+       } *uap = (struct a *) u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       flags = uap->flags + 1;
-       if ((flags&FTRUNCATE) && (flags&FWRITE) == 0) {
-               u.u_error = EINVAL;
-               return;
-       }
-       if (flags&FCREATE) {
-               ip = namei(uchar, CREATE, 1);
-               if (ip == NULL) {
-                       if (u.u_error)
-                               return;
-                       ip = maknode(uap->mode&07777&(~ISVTX));
-                       checkpermissions = 0;
-                       flags &= ~FTRUNCATE;
-               }
-       } else
-               ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       open1(ip, flags, checkpermissions);
+       copen(uap->mode-FOPEN, uap->crtmode);
 }
 
 }
 
-#ifndef NOCOMPAT
 /*
  * Creat system call.
  */
 /*
  * Creat system call.
  */
-ocreat()
+creat()
 {
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                int     fmode;
                char    *fname;
                int     fmode;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, CREATE, 1);
-       if (ip == NULL) {
-               if (u.u_error)
-                       return;
-               ip = maknode(uap->fmode&07777&(~ISVTX));
-               if (ip == NULL)
-                       return;
-               open1(ip, FWRITE, 0);
-       } else
-               open1(ip, FWRITE|FTRUNCATE, 1);
+       copen(FWRITE|FCREAT|FTRUNC, uap->fmode);
 }
 }
-#endif
 
 /*
  * Common code for open and creat.
 
 /*
  * Common code for open and creat.
- * Check permissions (if we haven't done so already),
- * allocate an open file structure, and call
- * the device open routine, if any.
+ * Check permissions, allocate an open file structure,
+ * and call the device open routine if any.
  */
  */
-open1(ip, mode, checkpermissions)
-       register struct inode *ip;
-       register mode;
+copen(mode, arg)
+       register int mode;
+       int arg;
 {
 {
+       register struct inode *ip;
        register struct file *fp;
        register struct file *fp;
-       int i, flags;
+       int i;
 
 
-       if (checkpermissions) {
+#ifdef notdef
+       if ((mode&(FREAD|FWRITE)) == 0) {
+               u.u_error = EINVAL;
+               return;
+       }
+#endif
+       if (mode&FCREAT) {
+               ip = namei(uchar, CREATE, 1);
+               if (ip == NULL) {
+                       if (u.u_error)
+                               return;
+                       ip = maknode(arg&07777&(~ISVTX));
+                       if (ip == NULL)
+                               return;
+                       mode &= ~FTRUNC;
+               } else {
+                       if (mode&FEXCL) {
+                               u.u_error = EEXIST;
+                               iput(ip);
+                               return;
+                       }
+                       mode &= ~FCREAT;
+               }
+       } else {
+               ip = namei(uchar, LOOKUP, 1);
+               if (ip == NULL)
+                       return;
+       }
+       if ((ip->i_mode & IFMT) == IFSOCK) {
+               u.u_error = EOPNOTSUPP;
+               goto bad;
+       }
+       if ((mode&FCREAT) == 0) {
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
@@ -154,36 +155,31 @@ open1(ip, mode, checkpermissions)
                        }
                }
        }
                        }
                }
        }
-
-       /*
-        * Check locking on inode.  Release "inode lock"
-        * while doing so in case we block inside flocki.
-        */
-       flags = 0;
-       if (mode&(FSHLOCK|FEXLOCK)) {
-               iunlock(ip);
-               flags = flocki(ip, 0, mode);
-               ilock(ip);
-               if (u.u_error)
-                       goto bad;
-       }
-       if (mode&FTRUNCATE)
+       fp = falloc();
+       if (fp == NULL)
+               goto bad;
+       if (mode&FTRUNC)
                itrunc(ip, (u_long)0);
        iunlock(ip);
                itrunc(ip, (u_long)0);
        iunlock(ip);
-       if ((fp = falloc()) == NULL)
-               goto out;
-       fp->f_flag = mode & FMODES;
-       fp->f_type = DTYPE_FILE;
+       fp->f_flag = mode&FMASK;
+       fp->f_type = DTYPE_INODE;
+       fp->f_ops = &inodeops;
+       fp->f_data = (caddr_t)ip;
        i = u.u_r.r_val1;
        i = u.u_r.r_val1;
-       fp->f_inode = ip;
-       u.u_error = openi(ip, mode);
-       if (u.u_error == 0) {
-               u.u_pofile[i] = flags;
+#ifdef notdef
+       if (setjmp(&u.u_qsave)) {
+               if (u.u_error == 0)
+                       u.u_error = EINTR;
+               u.u_ofile[i] = NULL;
+               closef(fp);
                return;
        }
                return;
        }
+#endif
+       u.u_error = openi(ip, mode);
+       if (u.u_error == 0)
+               return;
        u.u_ofile[i] = NULL;
        fp->f_count--;
        u.u_ofile[i] = NULL;
        fp->f_count--;
-out:
        irele(ip);
        return;
 bad:
        irele(ip);
        return;
 bad:
@@ -203,25 +199,30 @@ mknod()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       if (suser()) {
-               ip = namei(uchar, CREATE, 0);
-               if (ip != NULL) {
-                       u.u_error = EEXIST;
-                       goto out;
-               }
+       if (!suser())
+               return;
+       ip = namei(uchar, CREATE, 0);
+       if (ip != NULL) {
+               u.u_error = EEXIST;
+               goto out;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
-       if (uap->dev) {
-               /*
-                * Want to be able to use this to make badblock
-                * inodes, so don't truncate the dev number.
-                */
-               ip->i_rdev = uap->dev;
-               ip->i_flag |= IACC|IUPD|ICHG;
+       switch (ip->i_mode & IFMT) {
+
+       case IFCHR:
+       case IFBLK:
+               if (uap->dev) {
+                       /*
+                        * Want to be able to use this to make badblock
+                        * inodes, so don't truncate the dev number.
+                        */
+                       ip->i_rdev = uap->dev;
+                       ip->i_flag |= IACC|IUPD|ICHG;
+               }
        }
 
 out:
        }
 
 out:
@@ -367,17 +368,13 @@ lseek()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = ESPIPE;
-               return;
-       }
-       if (uap->sbase == FSEEK_RELATIVE)
+       if (uap->sbase == L_INCR)
                uap->off += fp->f_offset;
                uap->off += fp->f_offset;
-       else if (uap->sbase == FSEEK_EOF)
-               uap->off += fp->f_inode->i_size;
+       else if (uap->sbase == L_XTND)
+               uap->off += ((struct inode *)fp->f_data)->i_size;
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
@@ -401,11 +398,11 @@ saccess()
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
-               if ((uap->fmode&FACCESS_READ) && access(ip, IREAD))
+               if ((uap->fmode&R_OK) && access(ip, IREAD))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_WRITE) && access(ip, IWRITE))
+               if ((uap->fmode&W_OK) && access(ip, IWRITE))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_EXECUTE) && access(ip, IEXEC))
+               if ((uap->fmode&X_OK) && access(ip, IEXEC))
                        goto done;
 done:
                iput(ip);
                        goto done;
 done:
                iput(ip);
@@ -414,103 +411,41 @@ done:
        u.u_gid = svgid;
 }
 
        u.u_gid = svgid;
 }
 
-/*
- * the fstat system call.
- */
-fstat()
-{
-       register struct file *fp;
-       register struct a {
-               int     fd;
-               struct stat *sb;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
-       if (fp == NULL)
-               return;
-       if (fp->f_type == DTYPE_SOCKET)
-               u.u_error = sostat(fp->f_socket, uap->sb);
-       else
-               stat1(fp->f_inode, uap->sb);
-}
-
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
-       register struct inode *ip;
-       register struct a {
-               char    *fname;
-               struct stat *sb;
-       } *uap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       stat1(ip, uap->sb);
-       iput(ip);
+       stat1(1);
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
+{
+
+       stat1(0);
+}
+
+stat1(follow)
+       int follow;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
-               struct stat *sb;
+               struct stat *ub;
        } *uap;
        } *uap;
+       struct stat sb;
 
        uap = (struct a *)u.u_ap;
 
        uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 0);
+       ip = namei(uchar, LOOKUP, follow);
        if (ip == NULL)
                return;
        if (ip == NULL)
                return;
-       stat1(ip, uap->sb);
+       (void) statinode(ip, &sb);
        iput(ip);
        iput(ip);
-}
-
-/*
- * The basic routine for fstat and stat:
- * get the inode and pass appropriate parts back.
- */
-stat1(ip, ub)
-       register struct inode *ip;
-       struct stat *ub;
-{
-       struct stat ds;
-
-       IUPDAT(ip, &time, &time, 0);
-       /*
-        * Copy from inode table
-        */
-       ds.st_dev = ip->i_dev;
-       ds.st_ino = ip->i_number;
-       ds.st_mode = ip->i_mode;
-       ds.st_nlink = ip->i_nlink;
-       ds.st_uid = ip->i_uid;
-       ds.st_gid = ip->i_gid;
-       ds.st_rdev = (dev_t)ip->i_rdev;
-       ds.st_size = ip->i_size;
-       ds.st_atime = ip->i_atime;
-       ds.st_spare1 = 0;
-       ds.st_mtime = ip->i_mtime;
-       ds.st_spare2 = 0;
-       ds.st_ctime = ip->i_ctime;
-       ds.st_spare3 = 0;
-       /* this doesn't belong here */
-       if ((ip->i_mode&IFMT) == IFBLK)
-               ds.st_blksize = BLKDEV_IOSIZE;
-       else if ((ip->i_mode&IFMT) == IFCHR)
-               ds.st_blksize = MAXBSIZE;
-       else
-               ds.st_blksize = ip->i_fs->fs_bsize;
-       ds.st_blocks = ip->i_blocks;
-       ds.st_spare4[0] = ds.st_spare4[1] = 0;
-       u.u_error = copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds));
+       u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
 }
 
 /*
 }
 
 /*
@@ -570,14 +505,10 @@ fchmod()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
@@ -593,7 +524,6 @@ chmod1(ip, mode)
        register struct inode *ip;
        register int mode;
 {
        register struct inode *ip;
        register int mode;
 {
-       register int *gp;
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
@@ -640,14 +570,10 @@ fchown()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (!suser())
                return;
        ilock(ip);
        if (!suser())
                return;
        ilock(ip);
@@ -756,29 +682,24 @@ sync()
  */
 flock()
 {
  */
 flock()
 {
-       struct a {
+       register struct a {
                int     fd;
                int     how;
                int     fd;
                int     how;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
        register struct file *fp;
        register int cmd, flags;
 
        register struct file *fp;
        register int cmd, flags;
 
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {               /* XXX */
-               u.u_error = EINVAL;
-               return;
-       }
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
-       if (cmd&FUNLOCK) {
+       if (cmd&LOCK_UN) {
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
-               funlocki(fp->f_inode, flags);
+               funlocki((struct inode *)fp->f_data, flags);
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
@@ -786,10 +707,11 @@ flock()
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
-       if ((flags&UF_EXLOCK) && (cmd&FEXLOCK) ||
-           (flags&UF_SHLOCK) && (cmd&FSHLOCK))
+       if ((flags&UF_EXLOCK) && (cmd&LOCK_EX) ||
+           (flags&UF_SHLOCK) && (cmd&LOCK_SH))
                return;
                return;
-       u.u_pofile[uap->fd] = flocki(fp->f_inode, u.u_pofile[uap->fd], cmd);
+       u.u_pofile[uap->fd] =
+           flocki((struct inode *)fp->f_data, u.u_pofile[uap->fd], cmd);
 }
 
 /*
 }
 
 /*
@@ -829,18 +751,14 @@ ftruncate()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
@@ -857,14 +775,10 @@ fsync()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        syncip(ip);
        iunlock(ip);
        ilock(ip);
        syncip(ip);
        iunlock(ip);
@@ -1198,3 +1112,220 @@ maknode(mode)
        }
        return (ip);
 }
        }
        return (ip);
 }
+
+/*
+ * A virgin directory (no blushing please).
+ */
+struct dirtemplate mastertemplate = {
+       0, 12, 1, ".",
+       0, DIRBLKSIZ - 12, 2, ".."
+};
+
+/*
+ * Mkdir system call
+ */
+mkdir()
+{
+       struct a {
+               char    *name;
+               int     dmode;
+       } *uap;
+       register struct inode *ip, *dp;
+       struct dirtemplate dirtemplate;
+
+       uap = (struct a *)u.u_ap;
+       ip = namei(uchar, CREATE, 0);
+       if (u.u_error)
+               return;
+       if (ip != NULL) {
+               iput(ip);
+               u.u_error = EEXIST;
+               return;
+       }
+       dp = u.u_pdir;
+       uap->dmode &= 0777;
+       uap->dmode |= IFDIR;
+       /*
+        * Must simulate part of maknode here
+        * in order to acquire the inode, but
+        * not have it entered in the parent
+        * directory.  The entry is made later
+        * after writing "." and ".." entries out.
+        */
+       ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode);
+       if (ip == NULL) {
+               iput(dp);
+               return;
+       }
+#ifdef QUOTA
+       if (ip->i_dquot != NODQUOT)
+               panic("mkdir: dquot");
+#endif
+       ip->i_flag |= IACC|IUPD|ICHG;
+       ip->i_mode = uap->dmode & ~u.u_cmask;
+       ip->i_nlink = 2;
+       ip->i_uid = u.u_uid;
+       ip->i_gid = dp->i_gid;
+#ifdef QUOTA
+       ip->i_dquot = inoquota(ip);
+#endif
+       iupdat(ip, &time, &time, 1);
+
+       /*
+        * Bump link count in parent directory
+        * to reflect work done below.  Should
+        * be done before reference is created
+        * so reparation is possible if we crash.
+        */
+       dp->i_nlink++;
+       dp->i_flag |= ICHG;
+       iupdat(dp, &time, &time, 1);
+
+       /*
+        * Initialize directory with "."
+        * and ".." from static template.
+        */
+       dirtemplate = mastertemplate;
+       dirtemplate.dot_ino = ip->i_number;
+       dirtemplate.dotdot_ino = dp->i_number;
+       u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate,
+               sizeof (dirtemplate), (off_t)0, 1, (int *)0);
+       if (u.u_error) {
+               dp->i_nlink--;
+               dp->i_flag |= ICHG;
+               goto bad;
+       }
+       /*
+        * Directory all set up, now
+        * install the entry for it in
+        * the parent directory.
+        */
+       u.u_error = direnter(ip);
+       dp = NULL;
+       if (u.u_error) {
+               u.u_dirp = uap->name;
+               dp = namei(uchar, LOOKUP, 0);
+               if (dp) {
+                       dp->i_nlink--;
+                       dp->i_flag |= ICHG;
+               }
+       }
+bad:
+       /*
+        * No need to do an explicit itrunc here,
+        * irele will do this for us because we set
+        * the link count to 0.
+        */
+       if (u.u_error) {
+               ip->i_nlink = 0;
+               ip->i_flag |= ICHG;
+       }
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+/*
+ * Rmdir system call.
+ */
+rmdir()
+{
+       struct a {
+               char    *name;
+       };
+       register struct inode *ip, *dp;
+
+       ip = namei(uchar, DELETE | LOCKPARENT, 0);
+       if (ip == NULL)
+               return;
+       dp = u.u_pdir;
+       /*
+        * No rmdir "." please.
+        */
+       if (dp == ip) {
+               irele(dp);
+               iput(ip);
+               u.u_error = EINVAL;
+               return;
+       }
+       if ((ip->i_mode&IFMT) != IFDIR) {
+               u.u_error = ENOTDIR;
+               goto out;
+       }
+       /*
+        * Don't remove a mounted on directory.
+        */
+       if (ip->i_dev != dp->i_dev) {
+               u.u_error = EBUSY;
+               goto out;
+       }
+       /*
+        * Verify the directory is empty (and valid).
+        * (Rmdir ".." won't be valid since
+        *  ".." will contain a reference to
+        *  the current directory and thus be
+        *  non-empty.)
+        */
+       if (ip->i_nlink != 2 || !dirempty(ip)) {
+               u.u_error = ENOTEMPTY;
+               goto out;
+       }
+       /*
+        * Delete reference to directory before purging
+        * inode.  If we crash in between, the directory
+        * will be reattached to lost+found,
+        */
+       if (dirremove() == 0)
+               goto out;
+       dp->i_nlink--;
+       dp->i_flag |= ICHG;
+       iput(dp);
+       dp = NULL;
+       /*
+        * Truncate inode.  The only stuff left
+        * in the directory is "." and "..".  The
+        * "." reference is inconsequential since
+        * we're quashing it.  The ".." reference
+        * has already been adjusted above.  We've
+        * removed the "." reference and the reference
+        * in the parent directory, but there may be
+        * other hard links so decrement by 2 and
+        * worry about them later.
+        */
+       ip->i_nlink -= 2;
+       itrunc(ip, (u_long)0);
+out:
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+struct file *
+getinode(fdes)
+       int fdes;
+{
+       register struct file *fp;
+
+       fp = getf(fdes);
+       if (fp == 0)
+               return (0);
+       if (fp->f_type != DTYPE_INODE) {
+               u.u_error = EINVAL;
+               return (0);
+       }
+       return (fp);
+}
+
+/*
+ * mode mask for creation of files
+ */
+umask()
+{
+       register struct a {
+               int     mask;
+       } *uap;
+
+       uap = (struct a *)u.u_ap;
+       u.u_r.r_val1 = u.u_cmask;
+       u.u_cmask = uap->mask & 07777;
+}
index 39e00a7..dd8c07d 100644 (file)
@@ -1,4 +1,4 @@
-/*     vfs_vnops.c     4.34    83/03/31        */
+/*     vfs_vnops.c     4.35    83/05/27        */
 
 #include "../machine/reg.h"
 
 
 #include "../machine/reg.h"
 
 #include "../h/proc.h"
 #include "../h/nami.h"
 
 #include "../h/proc.h"
 #include "../h/nami.h"
 
-/*
- * Openi called to allow handler
- * of special files to initialize and
- * validate before actual IO.
- */
-openi(ip, mode)
-       register struct inode *ip;
-{
-       dev_t dev = (dev_t)ip->i_rdev;
-       register u_int maj = major(dev);
-
-       switch (ip->i_mode&IFMT) {
-
-       case IFCHR:
-               if (maj >= nchrdev)
-                       return (ENXIO);
-               return ((*cdevsw[maj].d_open)(dev, mode));
-
-       case IFBLK:
-               if (maj >= nblkdev)
-                       return (ENXIO);
-               return ((*bdevsw[maj].d_open)(dev, mode));
-       }
-       return (0);
-}
-
 /*
  * Check mode permission on inode pointer.
  * Mode is READ, WRITE or EXEC.
 /*
  * Check mode permission on inode pointer.
  * Mode is READ, WRITE or EXEC.
index 21b271f..46e70ea 100644 (file)
@@ -1,4 +1,4 @@
-/*     vfs_xxx.c       4.4     82/12/28        */
+/*     vfs_xxx.c       4.5     83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -38,7 +38,6 @@ uchar()
 #ifndef NOCOMPAT
 #include "../h/file.h"
 #include "../h/nami.h"
 #ifndef NOCOMPAT
 #include "../h/file.h"
 #include "../h/nami.h"
-#include "../h/descrip.h"
 #include "../h/kernel.h"
 
 /*
 #include "../h/kernel.h"
 
 /*
@@ -67,19 +66,13 @@ ofstat()
        register struct a {
                int     fd;
                struct ostat *sb;
        register struct a {
                int     fd;
                struct ostat *sb;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
+       extern struct file *getinode();
 
 
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               struct ostat ub;
-
-               bzero((caddr_t)&ub, sizeof (ub));
-               (void) copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub));
-       } else
-               ostat1(fp->f_inode, uap->sb);
+       ostat1((struct inode *)fp->f_data, uap->sb);
 }
 
 /*
 }
 
 /*
index 202225c..441a0d8 100644 (file)
@@ -1,4 +1,4 @@
-/*     ffs_alloc.c     2.25    83/05/21        */
+/*     ffs_alloc.c     2.26    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -887,13 +887,15 @@ mapsearch(fs, cgp, bpref, allocsiz)
        else
                start = cgp->cg_frotor / NBBY;
        len = howmany(fs->fs_fpg, NBBY) - start;
        else
                start = cgp->cg_frotor / NBBY;
        len = howmany(fs->fs_fpg, NBBY) - start;
-       loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag],
-               1 << (allocsiz - 1 + (fs->fs_frag % NBBY)));
+       loc = scanc((unsigned)len, (caddr_t)&cgp->cg_free[start],
+               (caddr_t)fragtbl[fs->fs_frag],
+               (int)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY))));
        if (loc == 0) {
                len = start + 1;
                start = 0;
        if (loc == 0) {
                len = start + 1;
                start = 0;
-               loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag],
-                       1 << (allocsiz - 1 + (fs->fs_frag % NBBY)));
+               loc = scanc((unsigned)len, (caddr_t)&cgp->cg_free[start],
+                       (caddr_t)fragtbl[fs->fs_frag],
+                       (int)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY))));
                if (loc == 0)
                        return (-1);
        }
                if (loc == 0)
                        return (-1);
        }
index f24149c..8adc5d4 100644 (file)
@@ -1,9 +1,9 @@
-/*     ffs_tables.c    2.3     82/07/15        */
+/*     ffs_tables.c    2.4     83/05/27        */
 
 #include "../h/param.h"
 
 /*
 
 #include "../h/param.h"
 
 /*
- * bit patterns for identifying fragments in the block map
+ * Bit patterns for identifying fragments in the block map
  * used as ((map & around) == inside)
  */
 int around[9] = {
  * used as ((map & around) == inside)
  */
 int around[9] = {
@@ -14,7 +14,7 @@ int inside[9] = {
 };
 
 /*
 };
 
 /*
- * given a block map bit pattern, the frag tables tell whether a
+ * Given a block map bit pattern, the frag tables tell whether a
  * particular size fragment is available. 
  *
  * used as:
  * particular size fragment is available. 
  *
  * used as:
@@ -25,8 +25,7 @@ int inside[9] = {
  * These tables are used by the scanc instruction on the VAX to
  * quickly find an appropriate fragment.
  */
  * These tables are used by the scanc instruction on the VAX to
  * quickly find an appropriate fragment.
  */
-
-unsigned char fragtbl124[256] = {
+u_char fragtbl124[256] = {
        0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e,
        0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a,
        0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
        0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e,
        0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a,
        0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
@@ -61,7 +60,7 @@ unsigned char fragtbl124[256] = {
        0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a,
 };
 
        0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a,
 };
 
-unsigned char fragtbl8[256] = {
+u_char fragtbl8[256] = {
        0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04,
        0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
        0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
        0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04,
        0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
        0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
@@ -97,8 +96,8 @@ unsigned char fragtbl8[256] = {
 };
 
 /*
 };
 
 /*
- * the actual fragtbl array
+ * The actual fragtbl array.
  */
  */
-unsigned char *fragtbl[MAXFRAG + 1] = {
+u_char *fragtbl[MAXFRAG + 1] = {
        0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
 };
        0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
 };
index cf56cad..55ddf67 100644 (file)
@@ -1,4 +1,4 @@
-/*     ffs_vnops.c     4.56    83/05/21        */
+/*     ffs_vnops.c     4.57    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
-#include "../h/descrip.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
+#include "../h/mount.h"
+
+extern struct fileops inodeops;
+struct file *getinode();
 
 /*
  * Change current working directory (``.'').
 
 /*
  * Change current working directory (``.'').
@@ -72,76 +75,74 @@ bad:
  */
 open()
 {
  */
 open()
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                char    *fname;
-               int     flags;
                int     mode;
                int     mode;
-       } *uap;
-       int checkpermissions = 1, flags;
+               int     crtmode;
+       } *uap = (struct a *) u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       flags = uap->flags + 1;
-       if ((flags&FTRUNCATE) && (flags&FWRITE) == 0) {
-               u.u_error = EINVAL;
-               return;
-       }
-       if (flags&FCREATE) {
-               ip = namei(uchar, CREATE, 1);
-               if (ip == NULL) {
-                       if (u.u_error)
-                               return;
-                       ip = maknode(uap->mode&07777&(~ISVTX));
-                       checkpermissions = 0;
-                       flags &= ~FTRUNCATE;
-               }
-       } else
-               ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       open1(ip, flags, checkpermissions);
+       copen(uap->mode-FOPEN, uap->crtmode);
 }
 
 }
 
-#ifndef NOCOMPAT
 /*
  * Creat system call.
  */
 /*
  * Creat system call.
  */
-ocreat()
+creat()
 {
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                int     fmode;
                char    *fname;
                int     fmode;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, CREATE, 1);
-       if (ip == NULL) {
-               if (u.u_error)
-                       return;
-               ip = maknode(uap->fmode&07777&(~ISVTX));
-               if (ip == NULL)
-                       return;
-               open1(ip, FWRITE, 0);
-       } else
-               open1(ip, FWRITE|FTRUNCATE, 1);
+       copen(FWRITE|FCREAT|FTRUNC, uap->fmode);
 }
 }
-#endif
 
 /*
  * Common code for open and creat.
 
 /*
  * Common code for open and creat.
- * Check permissions (if we haven't done so already),
- * allocate an open file structure, and call
- * the device open routine, if any.
+ * Check permissions, allocate an open file structure,
+ * and call the device open routine if any.
  */
  */
-open1(ip, mode, checkpermissions)
-       register struct inode *ip;
-       register mode;
+copen(mode, arg)
+       register int mode;
+       int arg;
 {
 {
+       register struct inode *ip;
        register struct file *fp;
        register struct file *fp;
-       int i, flags;
+       int i;
 
 
-       if (checkpermissions) {
+#ifdef notdef
+       if ((mode&(FREAD|FWRITE)) == 0) {
+               u.u_error = EINVAL;
+               return;
+       }
+#endif
+       if (mode&FCREAT) {
+               ip = namei(uchar, CREATE, 1);
+               if (ip == NULL) {
+                       if (u.u_error)
+                               return;
+                       ip = maknode(arg&07777&(~ISVTX));
+                       if (ip == NULL)
+                               return;
+                       mode &= ~FTRUNC;
+               } else {
+                       if (mode&FEXCL) {
+                               u.u_error = EEXIST;
+                               iput(ip);
+                               return;
+                       }
+                       mode &= ~FCREAT;
+               }
+       } else {
+               ip = namei(uchar, LOOKUP, 1);
+               if (ip == NULL)
+                       return;
+       }
+       if ((ip->i_mode & IFMT) == IFSOCK) {
+               u.u_error = EOPNOTSUPP;
+               goto bad;
+       }
+       if ((mode&FCREAT) == 0) {
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
@@ -154,36 +155,31 @@ open1(ip, mode, checkpermissions)
                        }
                }
        }
                        }
                }
        }
-
-       /*
-        * Check locking on inode.  Release "inode lock"
-        * while doing so in case we block inside flocki.
-        */
-       flags = 0;
-       if (mode&(FSHLOCK|FEXLOCK)) {
-               iunlock(ip);
-               flags = flocki(ip, 0, mode);
-               ilock(ip);
-               if (u.u_error)
-                       goto bad;
-       }
-       if (mode&FTRUNCATE)
+       fp = falloc();
+       if (fp == NULL)
+               goto bad;
+       if (mode&FTRUNC)
                itrunc(ip, (u_long)0);
        iunlock(ip);
                itrunc(ip, (u_long)0);
        iunlock(ip);
-       if ((fp = falloc()) == NULL)
-               goto out;
-       fp->f_flag = mode & FMODES;
-       fp->f_type = DTYPE_FILE;
+       fp->f_flag = mode&FMASK;
+       fp->f_type = DTYPE_INODE;
+       fp->f_ops = &inodeops;
+       fp->f_data = (caddr_t)ip;
        i = u.u_r.r_val1;
        i = u.u_r.r_val1;
-       fp->f_inode = ip;
-       u.u_error = openi(ip, mode);
-       if (u.u_error == 0) {
-               u.u_pofile[i] = flags;
+#ifdef notdef
+       if (setjmp(&u.u_qsave)) {
+               if (u.u_error == 0)
+                       u.u_error = EINTR;
+               u.u_ofile[i] = NULL;
+               closef(fp);
                return;
        }
                return;
        }
+#endif
+       u.u_error = openi(ip, mode);
+       if (u.u_error == 0)
+               return;
        u.u_ofile[i] = NULL;
        fp->f_count--;
        u.u_ofile[i] = NULL;
        fp->f_count--;
-out:
        irele(ip);
        return;
 bad:
        irele(ip);
        return;
 bad:
@@ -203,25 +199,30 @@ mknod()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       if (suser()) {
-               ip = namei(uchar, CREATE, 0);
-               if (ip != NULL) {
-                       u.u_error = EEXIST;
-                       goto out;
-               }
+       if (!suser())
+               return;
+       ip = namei(uchar, CREATE, 0);
+       if (ip != NULL) {
+               u.u_error = EEXIST;
+               goto out;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
-       if (uap->dev) {
-               /*
-                * Want to be able to use this to make badblock
-                * inodes, so don't truncate the dev number.
-                */
-               ip->i_rdev = uap->dev;
-               ip->i_flag |= IACC|IUPD|ICHG;
+       switch (ip->i_mode & IFMT) {
+
+       case IFCHR:
+       case IFBLK:
+               if (uap->dev) {
+                       /*
+                        * Want to be able to use this to make badblock
+                        * inodes, so don't truncate the dev number.
+                        */
+                       ip->i_rdev = uap->dev;
+                       ip->i_flag |= IACC|IUPD|ICHG;
+               }
        }
 
 out:
        }
 
 out:
@@ -367,17 +368,13 @@ lseek()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = ESPIPE;
-               return;
-       }
-       if (uap->sbase == FSEEK_RELATIVE)
+       if (uap->sbase == L_INCR)
                uap->off += fp->f_offset;
                uap->off += fp->f_offset;
-       else if (uap->sbase == FSEEK_EOF)
-               uap->off += fp->f_inode->i_size;
+       else if (uap->sbase == L_XTND)
+               uap->off += ((struct inode *)fp->f_data)->i_size;
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
@@ -401,11 +398,11 @@ saccess()
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
-               if ((uap->fmode&FACCESS_READ) && access(ip, IREAD))
+               if ((uap->fmode&R_OK) && access(ip, IREAD))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_WRITE) && access(ip, IWRITE))
+               if ((uap->fmode&W_OK) && access(ip, IWRITE))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_EXECUTE) && access(ip, IEXEC))
+               if ((uap->fmode&X_OK) && access(ip, IEXEC))
                        goto done;
 done:
                iput(ip);
                        goto done;
 done:
                iput(ip);
@@ -414,103 +411,41 @@ done:
        u.u_gid = svgid;
 }
 
        u.u_gid = svgid;
 }
 
-/*
- * the fstat system call.
- */
-fstat()
-{
-       register struct file *fp;
-       register struct a {
-               int     fd;
-               struct stat *sb;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
-       if (fp == NULL)
-               return;
-       if (fp->f_type == DTYPE_SOCKET)
-               u.u_error = sostat(fp->f_socket, uap->sb);
-       else
-               stat1(fp->f_inode, uap->sb);
-}
-
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
-       register struct inode *ip;
-       register struct a {
-               char    *fname;
-               struct stat *sb;
-       } *uap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       stat1(ip, uap->sb);
-       iput(ip);
+       stat1(1);
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
+{
+
+       stat1(0);
+}
+
+stat1(follow)
+       int follow;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
-               struct stat *sb;
+               struct stat *ub;
        } *uap;
        } *uap;
+       struct stat sb;
 
        uap = (struct a *)u.u_ap;
 
        uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 0);
+       ip = namei(uchar, LOOKUP, follow);
        if (ip == NULL)
                return;
        if (ip == NULL)
                return;
-       stat1(ip, uap->sb);
+       (void) statinode(ip, &sb);
        iput(ip);
        iput(ip);
-}
-
-/*
- * The basic routine for fstat and stat:
- * get the inode and pass appropriate parts back.
- */
-stat1(ip, ub)
-       register struct inode *ip;
-       struct stat *ub;
-{
-       struct stat ds;
-
-       IUPDAT(ip, &time, &time, 0);
-       /*
-        * Copy from inode table
-        */
-       ds.st_dev = ip->i_dev;
-       ds.st_ino = ip->i_number;
-       ds.st_mode = ip->i_mode;
-       ds.st_nlink = ip->i_nlink;
-       ds.st_uid = ip->i_uid;
-       ds.st_gid = ip->i_gid;
-       ds.st_rdev = (dev_t)ip->i_rdev;
-       ds.st_size = ip->i_size;
-       ds.st_atime = ip->i_atime;
-       ds.st_spare1 = 0;
-       ds.st_mtime = ip->i_mtime;
-       ds.st_spare2 = 0;
-       ds.st_ctime = ip->i_ctime;
-       ds.st_spare3 = 0;
-       /* this doesn't belong here */
-       if ((ip->i_mode&IFMT) == IFBLK)
-               ds.st_blksize = BLKDEV_IOSIZE;
-       else if ((ip->i_mode&IFMT) == IFCHR)
-               ds.st_blksize = MAXBSIZE;
-       else
-               ds.st_blksize = ip->i_fs->fs_bsize;
-       ds.st_blocks = ip->i_blocks;
-       ds.st_spare4[0] = ds.st_spare4[1] = 0;
-       u.u_error = copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds));
+       u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
 }
 
 /*
 }
 
 /*
@@ -570,14 +505,10 @@ fchmod()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
@@ -593,7 +524,6 @@ chmod1(ip, mode)
        register struct inode *ip;
        register int mode;
 {
        register struct inode *ip;
        register int mode;
 {
-       register int *gp;
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
@@ -640,14 +570,10 @@ fchown()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (!suser())
                return;
        ilock(ip);
        if (!suser())
                return;
        ilock(ip);
@@ -756,29 +682,24 @@ sync()
  */
 flock()
 {
  */
 flock()
 {
-       struct a {
+       register struct a {
                int     fd;
                int     how;
                int     fd;
                int     how;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
        register struct file *fp;
        register int cmd, flags;
 
        register struct file *fp;
        register int cmd, flags;
 
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {               /* XXX */
-               u.u_error = EINVAL;
-               return;
-       }
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
-       if (cmd&FUNLOCK) {
+       if (cmd&LOCK_UN) {
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
-               funlocki(fp->f_inode, flags);
+               funlocki((struct inode *)fp->f_data, flags);
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
@@ -786,10 +707,11 @@ flock()
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
-       if ((flags&UF_EXLOCK) && (cmd&FEXLOCK) ||
-           (flags&UF_SHLOCK) && (cmd&FSHLOCK))
+       if ((flags&UF_EXLOCK) && (cmd&LOCK_EX) ||
+           (flags&UF_SHLOCK) && (cmd&LOCK_SH))
                return;
                return;
-       u.u_pofile[uap->fd] = flocki(fp->f_inode, u.u_pofile[uap->fd], cmd);
+       u.u_pofile[uap->fd] =
+           flocki((struct inode *)fp->f_data, u.u_pofile[uap->fd], cmd);
 }
 
 /*
 }
 
 /*
@@ -829,18 +751,14 @@ ftruncate()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
@@ -857,14 +775,10 @@ fsync()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        syncip(ip);
        iunlock(ip);
        ilock(ip);
        syncip(ip);
        iunlock(ip);
@@ -1198,3 +1112,220 @@ maknode(mode)
        }
        return (ip);
 }
        }
        return (ip);
 }
+
+/*
+ * A virgin directory (no blushing please).
+ */
+struct dirtemplate mastertemplate = {
+       0, 12, 1, ".",
+       0, DIRBLKSIZ - 12, 2, ".."
+};
+
+/*
+ * Mkdir system call
+ */
+mkdir()
+{
+       struct a {
+               char    *name;
+               int     dmode;
+       } *uap;
+       register struct inode *ip, *dp;
+       struct dirtemplate dirtemplate;
+
+       uap = (struct a *)u.u_ap;
+       ip = namei(uchar, CREATE, 0);
+       if (u.u_error)
+               return;
+       if (ip != NULL) {
+               iput(ip);
+               u.u_error = EEXIST;
+               return;
+       }
+       dp = u.u_pdir;
+       uap->dmode &= 0777;
+       uap->dmode |= IFDIR;
+       /*
+        * Must simulate part of maknode here
+        * in order to acquire the inode, but
+        * not have it entered in the parent
+        * directory.  The entry is made later
+        * after writing "." and ".." entries out.
+        */
+       ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode);
+       if (ip == NULL) {
+               iput(dp);
+               return;
+       }
+#ifdef QUOTA
+       if (ip->i_dquot != NODQUOT)
+               panic("mkdir: dquot");
+#endif
+       ip->i_flag |= IACC|IUPD|ICHG;
+       ip->i_mode = uap->dmode & ~u.u_cmask;
+       ip->i_nlink = 2;
+       ip->i_uid = u.u_uid;
+       ip->i_gid = dp->i_gid;
+#ifdef QUOTA
+       ip->i_dquot = inoquota(ip);
+#endif
+       iupdat(ip, &time, &time, 1);
+
+       /*
+        * Bump link count in parent directory
+        * to reflect work done below.  Should
+        * be done before reference is created
+        * so reparation is possible if we crash.
+        */
+       dp->i_nlink++;
+       dp->i_flag |= ICHG;
+       iupdat(dp, &time, &time, 1);
+
+       /*
+        * Initialize directory with "."
+        * and ".." from static template.
+        */
+       dirtemplate = mastertemplate;
+       dirtemplate.dot_ino = ip->i_number;
+       dirtemplate.dotdot_ino = dp->i_number;
+       u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate,
+               sizeof (dirtemplate), (off_t)0, 1, (int *)0);
+       if (u.u_error) {
+               dp->i_nlink--;
+               dp->i_flag |= ICHG;
+               goto bad;
+       }
+       /*
+        * Directory all set up, now
+        * install the entry for it in
+        * the parent directory.
+        */
+       u.u_error = direnter(ip);
+       dp = NULL;
+       if (u.u_error) {
+               u.u_dirp = uap->name;
+               dp = namei(uchar, LOOKUP, 0);
+               if (dp) {
+                       dp->i_nlink--;
+                       dp->i_flag |= ICHG;
+               }
+       }
+bad:
+       /*
+        * No need to do an explicit itrunc here,
+        * irele will do this for us because we set
+        * the link count to 0.
+        */
+       if (u.u_error) {
+               ip->i_nlink = 0;
+               ip->i_flag |= ICHG;
+       }
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+/*
+ * Rmdir system call.
+ */
+rmdir()
+{
+       struct a {
+               char    *name;
+       };
+       register struct inode *ip, *dp;
+
+       ip = namei(uchar, DELETE | LOCKPARENT, 0);
+       if (ip == NULL)
+               return;
+       dp = u.u_pdir;
+       /*
+        * No rmdir "." please.
+        */
+       if (dp == ip) {
+               irele(dp);
+               iput(ip);
+               u.u_error = EINVAL;
+               return;
+       }
+       if ((ip->i_mode&IFMT) != IFDIR) {
+               u.u_error = ENOTDIR;
+               goto out;
+       }
+       /*
+        * Don't remove a mounted on directory.
+        */
+       if (ip->i_dev != dp->i_dev) {
+               u.u_error = EBUSY;
+               goto out;
+       }
+       /*
+        * Verify the directory is empty (and valid).
+        * (Rmdir ".." won't be valid since
+        *  ".." will contain a reference to
+        *  the current directory and thus be
+        *  non-empty.)
+        */
+       if (ip->i_nlink != 2 || !dirempty(ip)) {
+               u.u_error = ENOTEMPTY;
+               goto out;
+       }
+       /*
+        * Delete reference to directory before purging
+        * inode.  If we crash in between, the directory
+        * will be reattached to lost+found,
+        */
+       if (dirremove() == 0)
+               goto out;
+       dp->i_nlink--;
+       dp->i_flag |= ICHG;
+       iput(dp);
+       dp = NULL;
+       /*
+        * Truncate inode.  The only stuff left
+        * in the directory is "." and "..".  The
+        * "." reference is inconsequential since
+        * we're quashing it.  The ".." reference
+        * has already been adjusted above.  We've
+        * removed the "." reference and the reference
+        * in the parent directory, but there may be
+        * other hard links so decrement by 2 and
+        * worry about them later.
+        */
+       ip->i_nlink -= 2;
+       itrunc(ip, (u_long)0);
+out:
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+struct file *
+getinode(fdes)
+       int fdes;
+{
+       register struct file *fp;
+
+       fp = getf(fdes);
+       if (fp == 0)
+               return (0);
+       if (fp->f_type != DTYPE_INODE) {
+               u.u_error = EINVAL;
+               return (0);
+       }
+       return (fp);
+}
+
+/*
+ * mode mask for creation of files
+ */
+umask()
+{
+       register struct a {
+               int     mask;
+       } *uap;
+
+       uap = (struct a *)u.u_ap;
+       u.u_r.r_val1 = u.u_cmask;
+       u.u_cmask = uap->mask & 07777;
+}
index b6bbad2..a3fdf59 100644 (file)
@@ -1,4 +1,4 @@
-/*     ufs_vnops.c     4.56    83/05/21        */
+/*     ufs_vnops.c     4.57    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
-#include "../h/descrip.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
+#include "../h/mount.h"
+
+extern struct fileops inodeops;
+struct file *getinode();
 
 /*
  * Change current working directory (``.'').
 
 /*
  * Change current working directory (``.'').
@@ -72,76 +75,74 @@ bad:
  */
 open()
 {
  */
 open()
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                char    *fname;
-               int     flags;
                int     mode;
                int     mode;
-       } *uap;
-       int checkpermissions = 1, flags;
+               int     crtmode;
+       } *uap = (struct a *) u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       flags = uap->flags + 1;
-       if ((flags&FTRUNCATE) && (flags&FWRITE) == 0) {
-               u.u_error = EINVAL;
-               return;
-       }
-       if (flags&FCREATE) {
-               ip = namei(uchar, CREATE, 1);
-               if (ip == NULL) {
-                       if (u.u_error)
-                               return;
-                       ip = maknode(uap->mode&07777&(~ISVTX));
-                       checkpermissions = 0;
-                       flags &= ~FTRUNCATE;
-               }
-       } else
-               ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       open1(ip, flags, checkpermissions);
+       copen(uap->mode-FOPEN, uap->crtmode);
 }
 
 }
 
-#ifndef NOCOMPAT
 /*
  * Creat system call.
  */
 /*
  * Creat system call.
  */
-ocreat()
+creat()
 {
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                int     fmode;
                char    *fname;
                int     fmode;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, CREATE, 1);
-       if (ip == NULL) {
-               if (u.u_error)
-                       return;
-               ip = maknode(uap->fmode&07777&(~ISVTX));
-               if (ip == NULL)
-                       return;
-               open1(ip, FWRITE, 0);
-       } else
-               open1(ip, FWRITE|FTRUNCATE, 1);
+       copen(FWRITE|FCREAT|FTRUNC, uap->fmode);
 }
 }
-#endif
 
 /*
  * Common code for open and creat.
 
 /*
  * Common code for open and creat.
- * Check permissions (if we haven't done so already),
- * allocate an open file structure, and call
- * the device open routine, if any.
+ * Check permissions, allocate an open file structure,
+ * and call the device open routine if any.
  */
  */
-open1(ip, mode, checkpermissions)
-       register struct inode *ip;
-       register mode;
+copen(mode, arg)
+       register int mode;
+       int arg;
 {
 {
+       register struct inode *ip;
        register struct file *fp;
        register struct file *fp;
-       int i, flags;
+       int i;
 
 
-       if (checkpermissions) {
+#ifdef notdef
+       if ((mode&(FREAD|FWRITE)) == 0) {
+               u.u_error = EINVAL;
+               return;
+       }
+#endif
+       if (mode&FCREAT) {
+               ip = namei(uchar, CREATE, 1);
+               if (ip == NULL) {
+                       if (u.u_error)
+                               return;
+                       ip = maknode(arg&07777&(~ISVTX));
+                       if (ip == NULL)
+                               return;
+                       mode &= ~FTRUNC;
+               } else {
+                       if (mode&FEXCL) {
+                               u.u_error = EEXIST;
+                               iput(ip);
+                               return;
+                       }
+                       mode &= ~FCREAT;
+               }
+       } else {
+               ip = namei(uchar, LOOKUP, 1);
+               if (ip == NULL)
+                       return;
+       }
+       if ((ip->i_mode & IFMT) == IFSOCK) {
+               u.u_error = EOPNOTSUPP;
+               goto bad;
+       }
+       if ((mode&FCREAT) == 0) {
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
@@ -154,36 +155,31 @@ open1(ip, mode, checkpermissions)
                        }
                }
        }
                        }
                }
        }
-
-       /*
-        * Check locking on inode.  Release "inode lock"
-        * while doing so in case we block inside flocki.
-        */
-       flags = 0;
-       if (mode&(FSHLOCK|FEXLOCK)) {
-               iunlock(ip);
-               flags = flocki(ip, 0, mode);
-               ilock(ip);
-               if (u.u_error)
-                       goto bad;
-       }
-       if (mode&FTRUNCATE)
+       fp = falloc();
+       if (fp == NULL)
+               goto bad;
+       if (mode&FTRUNC)
                itrunc(ip, (u_long)0);
        iunlock(ip);
                itrunc(ip, (u_long)0);
        iunlock(ip);
-       if ((fp = falloc()) == NULL)
-               goto out;
-       fp->f_flag = mode & FMODES;
-       fp->f_type = DTYPE_FILE;
+       fp->f_flag = mode&FMASK;
+       fp->f_type = DTYPE_INODE;
+       fp->f_ops = &inodeops;
+       fp->f_data = (caddr_t)ip;
        i = u.u_r.r_val1;
        i = u.u_r.r_val1;
-       fp->f_inode = ip;
-       u.u_error = openi(ip, mode);
-       if (u.u_error == 0) {
-               u.u_pofile[i] = flags;
+#ifdef notdef
+       if (setjmp(&u.u_qsave)) {
+               if (u.u_error == 0)
+                       u.u_error = EINTR;
+               u.u_ofile[i] = NULL;
+               closef(fp);
                return;
        }
                return;
        }
+#endif
+       u.u_error = openi(ip, mode);
+       if (u.u_error == 0)
+               return;
        u.u_ofile[i] = NULL;
        fp->f_count--;
        u.u_ofile[i] = NULL;
        fp->f_count--;
-out:
        irele(ip);
        return;
 bad:
        irele(ip);
        return;
 bad:
@@ -203,25 +199,30 @@ mknod()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       if (suser()) {
-               ip = namei(uchar, CREATE, 0);
-               if (ip != NULL) {
-                       u.u_error = EEXIST;
-                       goto out;
-               }
+       if (!suser())
+               return;
+       ip = namei(uchar, CREATE, 0);
+       if (ip != NULL) {
+               u.u_error = EEXIST;
+               goto out;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
-       if (uap->dev) {
-               /*
-                * Want to be able to use this to make badblock
-                * inodes, so don't truncate the dev number.
-                */
-               ip->i_rdev = uap->dev;
-               ip->i_flag |= IACC|IUPD|ICHG;
+       switch (ip->i_mode & IFMT) {
+
+       case IFCHR:
+       case IFBLK:
+               if (uap->dev) {
+                       /*
+                        * Want to be able to use this to make badblock
+                        * inodes, so don't truncate the dev number.
+                        */
+                       ip->i_rdev = uap->dev;
+                       ip->i_flag |= IACC|IUPD|ICHG;
+               }
        }
 
 out:
        }
 
 out:
@@ -367,17 +368,13 @@ lseek()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = ESPIPE;
-               return;
-       }
-       if (uap->sbase == FSEEK_RELATIVE)
+       if (uap->sbase == L_INCR)
                uap->off += fp->f_offset;
                uap->off += fp->f_offset;
-       else if (uap->sbase == FSEEK_EOF)
-               uap->off += fp->f_inode->i_size;
+       else if (uap->sbase == L_XTND)
+               uap->off += ((struct inode *)fp->f_data)->i_size;
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
@@ -401,11 +398,11 @@ saccess()
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
-               if ((uap->fmode&FACCESS_READ) && access(ip, IREAD))
+               if ((uap->fmode&R_OK) && access(ip, IREAD))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_WRITE) && access(ip, IWRITE))
+               if ((uap->fmode&W_OK) && access(ip, IWRITE))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_EXECUTE) && access(ip, IEXEC))
+               if ((uap->fmode&X_OK) && access(ip, IEXEC))
                        goto done;
 done:
                iput(ip);
                        goto done;
 done:
                iput(ip);
@@ -414,103 +411,41 @@ done:
        u.u_gid = svgid;
 }
 
        u.u_gid = svgid;
 }
 
-/*
- * the fstat system call.
- */
-fstat()
-{
-       register struct file *fp;
-       register struct a {
-               int     fd;
-               struct stat *sb;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
-       if (fp == NULL)
-               return;
-       if (fp->f_type == DTYPE_SOCKET)
-               u.u_error = sostat(fp->f_socket, uap->sb);
-       else
-               stat1(fp->f_inode, uap->sb);
-}
-
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
-       register struct inode *ip;
-       register struct a {
-               char    *fname;
-               struct stat *sb;
-       } *uap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       stat1(ip, uap->sb);
-       iput(ip);
+       stat1(1);
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
+{
+
+       stat1(0);
+}
+
+stat1(follow)
+       int follow;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
-               struct stat *sb;
+               struct stat *ub;
        } *uap;
        } *uap;
+       struct stat sb;
 
        uap = (struct a *)u.u_ap;
 
        uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 0);
+       ip = namei(uchar, LOOKUP, follow);
        if (ip == NULL)
                return;
        if (ip == NULL)
                return;
-       stat1(ip, uap->sb);
+       (void) statinode(ip, &sb);
        iput(ip);
        iput(ip);
-}
-
-/*
- * The basic routine for fstat and stat:
- * get the inode and pass appropriate parts back.
- */
-stat1(ip, ub)
-       register struct inode *ip;
-       struct stat *ub;
-{
-       struct stat ds;
-
-       IUPDAT(ip, &time, &time, 0);
-       /*
-        * Copy from inode table
-        */
-       ds.st_dev = ip->i_dev;
-       ds.st_ino = ip->i_number;
-       ds.st_mode = ip->i_mode;
-       ds.st_nlink = ip->i_nlink;
-       ds.st_uid = ip->i_uid;
-       ds.st_gid = ip->i_gid;
-       ds.st_rdev = (dev_t)ip->i_rdev;
-       ds.st_size = ip->i_size;
-       ds.st_atime = ip->i_atime;
-       ds.st_spare1 = 0;
-       ds.st_mtime = ip->i_mtime;
-       ds.st_spare2 = 0;
-       ds.st_ctime = ip->i_ctime;
-       ds.st_spare3 = 0;
-       /* this doesn't belong here */
-       if ((ip->i_mode&IFMT) == IFBLK)
-               ds.st_blksize = BLKDEV_IOSIZE;
-       else if ((ip->i_mode&IFMT) == IFCHR)
-               ds.st_blksize = MAXBSIZE;
-       else
-               ds.st_blksize = ip->i_fs->fs_bsize;
-       ds.st_blocks = ip->i_blocks;
-       ds.st_spare4[0] = ds.st_spare4[1] = 0;
-       u.u_error = copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds));
+       u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
 }
 
 /*
 }
 
 /*
@@ -570,14 +505,10 @@ fchmod()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
@@ -593,7 +524,6 @@ chmod1(ip, mode)
        register struct inode *ip;
        register int mode;
 {
        register struct inode *ip;
        register int mode;
 {
-       register int *gp;
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
@@ -640,14 +570,10 @@ fchown()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (!suser())
                return;
        ilock(ip);
        if (!suser())
                return;
        ilock(ip);
@@ -756,29 +682,24 @@ sync()
  */
 flock()
 {
  */
 flock()
 {
-       struct a {
+       register struct a {
                int     fd;
                int     how;
                int     fd;
                int     how;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
        register struct file *fp;
        register int cmd, flags;
 
        register struct file *fp;
        register int cmd, flags;
 
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {               /* XXX */
-               u.u_error = EINVAL;
-               return;
-       }
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
-       if (cmd&FUNLOCK) {
+       if (cmd&LOCK_UN) {
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
-               funlocki(fp->f_inode, flags);
+               funlocki((struct inode *)fp->f_data, flags);
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
@@ -786,10 +707,11 @@ flock()
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
-       if ((flags&UF_EXLOCK) && (cmd&FEXLOCK) ||
-           (flags&UF_SHLOCK) && (cmd&FSHLOCK))
+       if ((flags&UF_EXLOCK) && (cmd&LOCK_EX) ||
+           (flags&UF_SHLOCK) && (cmd&LOCK_SH))
                return;
                return;
-       u.u_pofile[uap->fd] = flocki(fp->f_inode, u.u_pofile[uap->fd], cmd);
+       u.u_pofile[uap->fd] =
+           flocki((struct inode *)fp->f_data, u.u_pofile[uap->fd], cmd);
 }
 
 /*
 }
 
 /*
@@ -829,18 +751,14 @@ ftruncate()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
@@ -857,14 +775,10 @@ fsync()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        syncip(ip);
        iunlock(ip);
        ilock(ip);
        syncip(ip);
        iunlock(ip);
@@ -1198,3 +1112,220 @@ maknode(mode)
        }
        return (ip);
 }
        }
        return (ip);
 }
+
+/*
+ * A virgin directory (no blushing please).
+ */
+struct dirtemplate mastertemplate = {
+       0, 12, 1, ".",
+       0, DIRBLKSIZ - 12, 2, ".."
+};
+
+/*
+ * Mkdir system call
+ */
+mkdir()
+{
+       struct a {
+               char    *name;
+               int     dmode;
+       } *uap;
+       register struct inode *ip, *dp;
+       struct dirtemplate dirtemplate;
+
+       uap = (struct a *)u.u_ap;
+       ip = namei(uchar, CREATE, 0);
+       if (u.u_error)
+               return;
+       if (ip != NULL) {
+               iput(ip);
+               u.u_error = EEXIST;
+               return;
+       }
+       dp = u.u_pdir;
+       uap->dmode &= 0777;
+       uap->dmode |= IFDIR;
+       /*
+        * Must simulate part of maknode here
+        * in order to acquire the inode, but
+        * not have it entered in the parent
+        * directory.  The entry is made later
+        * after writing "." and ".." entries out.
+        */
+       ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode);
+       if (ip == NULL) {
+               iput(dp);
+               return;
+       }
+#ifdef QUOTA
+       if (ip->i_dquot != NODQUOT)
+               panic("mkdir: dquot");
+#endif
+       ip->i_flag |= IACC|IUPD|ICHG;
+       ip->i_mode = uap->dmode & ~u.u_cmask;
+       ip->i_nlink = 2;
+       ip->i_uid = u.u_uid;
+       ip->i_gid = dp->i_gid;
+#ifdef QUOTA
+       ip->i_dquot = inoquota(ip);
+#endif
+       iupdat(ip, &time, &time, 1);
+
+       /*
+        * Bump link count in parent directory
+        * to reflect work done below.  Should
+        * be done before reference is created
+        * so reparation is possible if we crash.
+        */
+       dp->i_nlink++;
+       dp->i_flag |= ICHG;
+       iupdat(dp, &time, &time, 1);
+
+       /*
+        * Initialize directory with "."
+        * and ".." from static template.
+        */
+       dirtemplate = mastertemplate;
+       dirtemplate.dot_ino = ip->i_number;
+       dirtemplate.dotdot_ino = dp->i_number;
+       u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate,
+               sizeof (dirtemplate), (off_t)0, 1, (int *)0);
+       if (u.u_error) {
+               dp->i_nlink--;
+               dp->i_flag |= ICHG;
+               goto bad;
+       }
+       /*
+        * Directory all set up, now
+        * install the entry for it in
+        * the parent directory.
+        */
+       u.u_error = direnter(ip);
+       dp = NULL;
+       if (u.u_error) {
+               u.u_dirp = uap->name;
+               dp = namei(uchar, LOOKUP, 0);
+               if (dp) {
+                       dp->i_nlink--;
+                       dp->i_flag |= ICHG;
+               }
+       }
+bad:
+       /*
+        * No need to do an explicit itrunc here,
+        * irele will do this for us because we set
+        * the link count to 0.
+        */
+       if (u.u_error) {
+               ip->i_nlink = 0;
+               ip->i_flag |= ICHG;
+       }
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+/*
+ * Rmdir system call.
+ */
+rmdir()
+{
+       struct a {
+               char    *name;
+       };
+       register struct inode *ip, *dp;
+
+       ip = namei(uchar, DELETE | LOCKPARENT, 0);
+       if (ip == NULL)
+               return;
+       dp = u.u_pdir;
+       /*
+        * No rmdir "." please.
+        */
+       if (dp == ip) {
+               irele(dp);
+               iput(ip);
+               u.u_error = EINVAL;
+               return;
+       }
+       if ((ip->i_mode&IFMT) != IFDIR) {
+               u.u_error = ENOTDIR;
+               goto out;
+       }
+       /*
+        * Don't remove a mounted on directory.
+        */
+       if (ip->i_dev != dp->i_dev) {
+               u.u_error = EBUSY;
+               goto out;
+       }
+       /*
+        * Verify the directory is empty (and valid).
+        * (Rmdir ".." won't be valid since
+        *  ".." will contain a reference to
+        *  the current directory and thus be
+        *  non-empty.)
+        */
+       if (ip->i_nlink != 2 || !dirempty(ip)) {
+               u.u_error = ENOTEMPTY;
+               goto out;
+       }
+       /*
+        * Delete reference to directory before purging
+        * inode.  If we crash in between, the directory
+        * will be reattached to lost+found,
+        */
+       if (dirremove() == 0)
+               goto out;
+       dp->i_nlink--;
+       dp->i_flag |= ICHG;
+       iput(dp);
+       dp = NULL;
+       /*
+        * Truncate inode.  The only stuff left
+        * in the directory is "." and "..".  The
+        * "." reference is inconsequential since
+        * we're quashing it.  The ".." reference
+        * has already been adjusted above.  We've
+        * removed the "." reference and the reference
+        * in the parent directory, but there may be
+        * other hard links so decrement by 2 and
+        * worry about them later.
+        */
+       ip->i_nlink -= 2;
+       itrunc(ip, (u_long)0);
+out:
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+struct file *
+getinode(fdes)
+       int fdes;
+{
+       register struct file *fp;
+
+       fp = getf(fdes);
+       if (fp == 0)
+               return (0);
+       if (fp->f_type != DTYPE_INODE) {
+               u.u_error = EINVAL;
+               return (0);
+       }
+       return (fp);
+}
+
+/*
+ * mode mask for creation of files
+ */
+umask()
+{
+       register struct a {
+               int     mask;
+       } *uap;
+
+       uap = (struct a *)u.u_ap;
+       u.u_r.r_val1 = u.u_cmask;
+       u.u_cmask = uap->mask & 07777;
+}
index c126871..a193628 100644 (file)
@@ -1,4 +1,4 @@
-/*     lfs_alloc.c     2.25    83/05/21        */
+/*     lfs_alloc.c     2.26    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -887,13 +887,15 @@ mapsearch(fs, cgp, bpref, allocsiz)
        else
                start = cgp->cg_frotor / NBBY;
        len = howmany(fs->fs_fpg, NBBY) - start;
        else
                start = cgp->cg_frotor / NBBY;
        len = howmany(fs->fs_fpg, NBBY) - start;
-       loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag],
-               1 << (allocsiz - 1 + (fs->fs_frag % NBBY)));
+       loc = scanc((unsigned)len, (caddr_t)&cgp->cg_free[start],
+               (caddr_t)fragtbl[fs->fs_frag],
+               (int)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY))));
        if (loc == 0) {
                len = start + 1;
                start = 0;
        if (loc == 0) {
                len = start + 1;
                start = 0;
-               loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag],
-                       1 << (allocsiz - 1 + (fs->fs_frag % NBBY)));
+               loc = scanc((unsigned)len, (caddr_t)&cgp->cg_free[start],
+                       (caddr_t)fragtbl[fs->fs_frag],
+                       (int)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY))));
                if (loc == 0)
                        return (-1);
        }
                if (loc == 0)
                        return (-1);
        }
index 7ec51dc..b5e8dce 100644 (file)
@@ -1,4 +1,4 @@
-/*     lfs_vnops.c     4.56    83/05/21        */
+/*     lfs_vnops.c     4.57    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
-#include "../h/descrip.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
+#include "../h/mount.h"
+
+extern struct fileops inodeops;
+struct file *getinode();
 
 /*
  * Change current working directory (``.'').
 
 /*
  * Change current working directory (``.'').
@@ -72,76 +75,74 @@ bad:
  */
 open()
 {
  */
 open()
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                char    *fname;
-               int     flags;
                int     mode;
                int     mode;
-       } *uap;
-       int checkpermissions = 1, flags;
+               int     crtmode;
+       } *uap = (struct a *) u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       flags = uap->flags + 1;
-       if ((flags&FTRUNCATE) && (flags&FWRITE) == 0) {
-               u.u_error = EINVAL;
-               return;
-       }
-       if (flags&FCREATE) {
-               ip = namei(uchar, CREATE, 1);
-               if (ip == NULL) {
-                       if (u.u_error)
-                               return;
-                       ip = maknode(uap->mode&07777&(~ISVTX));
-                       checkpermissions = 0;
-                       flags &= ~FTRUNCATE;
-               }
-       } else
-               ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       open1(ip, flags, checkpermissions);
+       copen(uap->mode-FOPEN, uap->crtmode);
 }
 
 }
 
-#ifndef NOCOMPAT
 /*
  * Creat system call.
  */
 /*
  * Creat system call.
  */
-ocreat()
+creat()
 {
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                int     fmode;
                char    *fname;
                int     fmode;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, CREATE, 1);
-       if (ip == NULL) {
-               if (u.u_error)
-                       return;
-               ip = maknode(uap->fmode&07777&(~ISVTX));
-               if (ip == NULL)
-                       return;
-               open1(ip, FWRITE, 0);
-       } else
-               open1(ip, FWRITE|FTRUNCATE, 1);
+       copen(FWRITE|FCREAT|FTRUNC, uap->fmode);
 }
 }
-#endif
 
 /*
  * Common code for open and creat.
 
 /*
  * Common code for open and creat.
- * Check permissions (if we haven't done so already),
- * allocate an open file structure, and call
- * the device open routine, if any.
+ * Check permissions, allocate an open file structure,
+ * and call the device open routine if any.
  */
  */
-open1(ip, mode, checkpermissions)
-       register struct inode *ip;
-       register mode;
+copen(mode, arg)
+       register int mode;
+       int arg;
 {
 {
+       register struct inode *ip;
        register struct file *fp;
        register struct file *fp;
-       int i, flags;
+       int i;
 
 
-       if (checkpermissions) {
+#ifdef notdef
+       if ((mode&(FREAD|FWRITE)) == 0) {
+               u.u_error = EINVAL;
+               return;
+       }
+#endif
+       if (mode&FCREAT) {
+               ip = namei(uchar, CREATE, 1);
+               if (ip == NULL) {
+                       if (u.u_error)
+                               return;
+                       ip = maknode(arg&07777&(~ISVTX));
+                       if (ip == NULL)
+                               return;
+                       mode &= ~FTRUNC;
+               } else {
+                       if (mode&FEXCL) {
+                               u.u_error = EEXIST;
+                               iput(ip);
+                               return;
+                       }
+                       mode &= ~FCREAT;
+               }
+       } else {
+               ip = namei(uchar, LOOKUP, 1);
+               if (ip == NULL)
+                       return;
+       }
+       if ((ip->i_mode & IFMT) == IFSOCK) {
+               u.u_error = EOPNOTSUPP;
+               goto bad;
+       }
+       if ((mode&FCREAT) == 0) {
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
@@ -154,36 +155,31 @@ open1(ip, mode, checkpermissions)
                        }
                }
        }
                        }
                }
        }
-
-       /*
-        * Check locking on inode.  Release "inode lock"
-        * while doing so in case we block inside flocki.
-        */
-       flags = 0;
-       if (mode&(FSHLOCK|FEXLOCK)) {
-               iunlock(ip);
-               flags = flocki(ip, 0, mode);
-               ilock(ip);
-               if (u.u_error)
-                       goto bad;
-       }
-       if (mode&FTRUNCATE)
+       fp = falloc();
+       if (fp == NULL)
+               goto bad;
+       if (mode&FTRUNC)
                itrunc(ip, (u_long)0);
        iunlock(ip);
                itrunc(ip, (u_long)0);
        iunlock(ip);
-       if ((fp = falloc()) == NULL)
-               goto out;
-       fp->f_flag = mode & FMODES;
-       fp->f_type = DTYPE_FILE;
+       fp->f_flag = mode&FMASK;
+       fp->f_type = DTYPE_INODE;
+       fp->f_ops = &inodeops;
+       fp->f_data = (caddr_t)ip;
        i = u.u_r.r_val1;
        i = u.u_r.r_val1;
-       fp->f_inode = ip;
-       u.u_error = openi(ip, mode);
-       if (u.u_error == 0) {
-               u.u_pofile[i] = flags;
+#ifdef notdef
+       if (setjmp(&u.u_qsave)) {
+               if (u.u_error == 0)
+                       u.u_error = EINTR;
+               u.u_ofile[i] = NULL;
+               closef(fp);
                return;
        }
                return;
        }
+#endif
+       u.u_error = openi(ip, mode);
+       if (u.u_error == 0)
+               return;
        u.u_ofile[i] = NULL;
        fp->f_count--;
        u.u_ofile[i] = NULL;
        fp->f_count--;
-out:
        irele(ip);
        return;
 bad:
        irele(ip);
        return;
 bad:
@@ -203,25 +199,30 @@ mknod()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       if (suser()) {
-               ip = namei(uchar, CREATE, 0);
-               if (ip != NULL) {
-                       u.u_error = EEXIST;
-                       goto out;
-               }
+       if (!suser())
+               return;
+       ip = namei(uchar, CREATE, 0);
+       if (ip != NULL) {
+               u.u_error = EEXIST;
+               goto out;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
-       if (uap->dev) {
-               /*
-                * Want to be able to use this to make badblock
-                * inodes, so don't truncate the dev number.
-                */
-               ip->i_rdev = uap->dev;
-               ip->i_flag |= IACC|IUPD|ICHG;
+       switch (ip->i_mode & IFMT) {
+
+       case IFCHR:
+       case IFBLK:
+               if (uap->dev) {
+                       /*
+                        * Want to be able to use this to make badblock
+                        * inodes, so don't truncate the dev number.
+                        */
+                       ip->i_rdev = uap->dev;
+                       ip->i_flag |= IACC|IUPD|ICHG;
+               }
        }
 
 out:
        }
 
 out:
@@ -367,17 +368,13 @@ lseek()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = ESPIPE;
-               return;
-       }
-       if (uap->sbase == FSEEK_RELATIVE)
+       if (uap->sbase == L_INCR)
                uap->off += fp->f_offset;
                uap->off += fp->f_offset;
-       else if (uap->sbase == FSEEK_EOF)
-               uap->off += fp->f_inode->i_size;
+       else if (uap->sbase == L_XTND)
+               uap->off += ((struct inode *)fp->f_data)->i_size;
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
@@ -401,11 +398,11 @@ saccess()
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
-               if ((uap->fmode&FACCESS_READ) && access(ip, IREAD))
+               if ((uap->fmode&R_OK) && access(ip, IREAD))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_WRITE) && access(ip, IWRITE))
+               if ((uap->fmode&W_OK) && access(ip, IWRITE))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_EXECUTE) && access(ip, IEXEC))
+               if ((uap->fmode&X_OK) && access(ip, IEXEC))
                        goto done;
 done:
                iput(ip);
                        goto done;
 done:
                iput(ip);
@@ -414,103 +411,41 @@ done:
        u.u_gid = svgid;
 }
 
        u.u_gid = svgid;
 }
 
-/*
- * the fstat system call.
- */
-fstat()
-{
-       register struct file *fp;
-       register struct a {
-               int     fd;
-               struct stat *sb;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
-       if (fp == NULL)
-               return;
-       if (fp->f_type == DTYPE_SOCKET)
-               u.u_error = sostat(fp->f_socket, uap->sb);
-       else
-               stat1(fp->f_inode, uap->sb);
-}
-
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
-       register struct inode *ip;
-       register struct a {
-               char    *fname;
-               struct stat *sb;
-       } *uap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       stat1(ip, uap->sb);
-       iput(ip);
+       stat1(1);
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
+{
+
+       stat1(0);
+}
+
+stat1(follow)
+       int follow;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
-               struct stat *sb;
+               struct stat *ub;
        } *uap;
        } *uap;
+       struct stat sb;
 
        uap = (struct a *)u.u_ap;
 
        uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 0);
+       ip = namei(uchar, LOOKUP, follow);
        if (ip == NULL)
                return;
        if (ip == NULL)
                return;
-       stat1(ip, uap->sb);
+       (void) statinode(ip, &sb);
        iput(ip);
        iput(ip);
-}
-
-/*
- * The basic routine for fstat and stat:
- * get the inode and pass appropriate parts back.
- */
-stat1(ip, ub)
-       register struct inode *ip;
-       struct stat *ub;
-{
-       struct stat ds;
-
-       IUPDAT(ip, &time, &time, 0);
-       /*
-        * Copy from inode table
-        */
-       ds.st_dev = ip->i_dev;
-       ds.st_ino = ip->i_number;
-       ds.st_mode = ip->i_mode;
-       ds.st_nlink = ip->i_nlink;
-       ds.st_uid = ip->i_uid;
-       ds.st_gid = ip->i_gid;
-       ds.st_rdev = (dev_t)ip->i_rdev;
-       ds.st_size = ip->i_size;
-       ds.st_atime = ip->i_atime;
-       ds.st_spare1 = 0;
-       ds.st_mtime = ip->i_mtime;
-       ds.st_spare2 = 0;
-       ds.st_ctime = ip->i_ctime;
-       ds.st_spare3 = 0;
-       /* this doesn't belong here */
-       if ((ip->i_mode&IFMT) == IFBLK)
-               ds.st_blksize = BLKDEV_IOSIZE;
-       else if ((ip->i_mode&IFMT) == IFCHR)
-               ds.st_blksize = MAXBSIZE;
-       else
-               ds.st_blksize = ip->i_fs->fs_bsize;
-       ds.st_blocks = ip->i_blocks;
-       ds.st_spare4[0] = ds.st_spare4[1] = 0;
-       u.u_error = copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds));
+       u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
 }
 
 /*
 }
 
 /*
@@ -570,14 +505,10 @@ fchmod()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
@@ -593,7 +524,6 @@ chmod1(ip, mode)
        register struct inode *ip;
        register int mode;
 {
        register struct inode *ip;
        register int mode;
 {
-       register int *gp;
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
@@ -640,14 +570,10 @@ fchown()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (!suser())
                return;
        ilock(ip);
        if (!suser())
                return;
        ilock(ip);
@@ -756,29 +682,24 @@ sync()
  */
 flock()
 {
  */
 flock()
 {
-       struct a {
+       register struct a {
                int     fd;
                int     how;
                int     fd;
                int     how;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
        register struct file *fp;
        register int cmd, flags;
 
        register struct file *fp;
        register int cmd, flags;
 
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {               /* XXX */
-               u.u_error = EINVAL;
-               return;
-       }
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
-       if (cmd&FUNLOCK) {
+       if (cmd&LOCK_UN) {
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
-               funlocki(fp->f_inode, flags);
+               funlocki((struct inode *)fp->f_data, flags);
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
@@ -786,10 +707,11 @@ flock()
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
-       if ((flags&UF_EXLOCK) && (cmd&FEXLOCK) ||
-           (flags&UF_SHLOCK) && (cmd&FSHLOCK))
+       if ((flags&UF_EXLOCK) && (cmd&LOCK_EX) ||
+           (flags&UF_SHLOCK) && (cmd&LOCK_SH))
                return;
                return;
-       u.u_pofile[uap->fd] = flocki(fp->f_inode, u.u_pofile[uap->fd], cmd);
+       u.u_pofile[uap->fd] =
+           flocki((struct inode *)fp->f_data, u.u_pofile[uap->fd], cmd);
 }
 
 /*
 }
 
 /*
@@ -829,18 +751,14 @@ ftruncate()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
@@ -857,14 +775,10 @@ fsync()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        syncip(ip);
        iunlock(ip);
        ilock(ip);
        syncip(ip);
        iunlock(ip);
@@ -1198,3 +1112,220 @@ maknode(mode)
        }
        return (ip);
 }
        }
        return (ip);
 }
+
+/*
+ * A virgin directory (no blushing please).
+ */
+struct dirtemplate mastertemplate = {
+       0, 12, 1, ".",
+       0, DIRBLKSIZ - 12, 2, ".."
+};
+
+/*
+ * Mkdir system call
+ */
+mkdir()
+{
+       struct a {
+               char    *name;
+               int     dmode;
+       } *uap;
+       register struct inode *ip, *dp;
+       struct dirtemplate dirtemplate;
+
+       uap = (struct a *)u.u_ap;
+       ip = namei(uchar, CREATE, 0);
+       if (u.u_error)
+               return;
+       if (ip != NULL) {
+               iput(ip);
+               u.u_error = EEXIST;
+               return;
+       }
+       dp = u.u_pdir;
+       uap->dmode &= 0777;
+       uap->dmode |= IFDIR;
+       /*
+        * Must simulate part of maknode here
+        * in order to acquire the inode, but
+        * not have it entered in the parent
+        * directory.  The entry is made later
+        * after writing "." and ".." entries out.
+        */
+       ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode);
+       if (ip == NULL) {
+               iput(dp);
+               return;
+       }
+#ifdef QUOTA
+       if (ip->i_dquot != NODQUOT)
+               panic("mkdir: dquot");
+#endif
+       ip->i_flag |= IACC|IUPD|ICHG;
+       ip->i_mode = uap->dmode & ~u.u_cmask;
+       ip->i_nlink = 2;
+       ip->i_uid = u.u_uid;
+       ip->i_gid = dp->i_gid;
+#ifdef QUOTA
+       ip->i_dquot = inoquota(ip);
+#endif
+       iupdat(ip, &time, &time, 1);
+
+       /*
+        * Bump link count in parent directory
+        * to reflect work done below.  Should
+        * be done before reference is created
+        * so reparation is possible if we crash.
+        */
+       dp->i_nlink++;
+       dp->i_flag |= ICHG;
+       iupdat(dp, &time, &time, 1);
+
+       /*
+        * Initialize directory with "."
+        * and ".." from static template.
+        */
+       dirtemplate = mastertemplate;
+       dirtemplate.dot_ino = ip->i_number;
+       dirtemplate.dotdot_ino = dp->i_number;
+       u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate,
+               sizeof (dirtemplate), (off_t)0, 1, (int *)0);
+       if (u.u_error) {
+               dp->i_nlink--;
+               dp->i_flag |= ICHG;
+               goto bad;
+       }
+       /*
+        * Directory all set up, now
+        * install the entry for it in
+        * the parent directory.
+        */
+       u.u_error = direnter(ip);
+       dp = NULL;
+       if (u.u_error) {
+               u.u_dirp = uap->name;
+               dp = namei(uchar, LOOKUP, 0);
+               if (dp) {
+                       dp->i_nlink--;
+                       dp->i_flag |= ICHG;
+               }
+       }
+bad:
+       /*
+        * No need to do an explicit itrunc here,
+        * irele will do this for us because we set
+        * the link count to 0.
+        */
+       if (u.u_error) {
+               ip->i_nlink = 0;
+               ip->i_flag |= ICHG;
+       }
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+/*
+ * Rmdir system call.
+ */
+rmdir()
+{
+       struct a {
+               char    *name;
+       };
+       register struct inode *ip, *dp;
+
+       ip = namei(uchar, DELETE | LOCKPARENT, 0);
+       if (ip == NULL)
+               return;
+       dp = u.u_pdir;
+       /*
+        * No rmdir "." please.
+        */
+       if (dp == ip) {
+               irele(dp);
+               iput(ip);
+               u.u_error = EINVAL;
+               return;
+       }
+       if ((ip->i_mode&IFMT) != IFDIR) {
+               u.u_error = ENOTDIR;
+               goto out;
+       }
+       /*
+        * Don't remove a mounted on directory.
+        */
+       if (ip->i_dev != dp->i_dev) {
+               u.u_error = EBUSY;
+               goto out;
+       }
+       /*
+        * Verify the directory is empty (and valid).
+        * (Rmdir ".." won't be valid since
+        *  ".." will contain a reference to
+        *  the current directory and thus be
+        *  non-empty.)
+        */
+       if (ip->i_nlink != 2 || !dirempty(ip)) {
+               u.u_error = ENOTEMPTY;
+               goto out;
+       }
+       /*
+        * Delete reference to directory before purging
+        * inode.  If we crash in between, the directory
+        * will be reattached to lost+found,
+        */
+       if (dirremove() == 0)
+               goto out;
+       dp->i_nlink--;
+       dp->i_flag |= ICHG;
+       iput(dp);
+       dp = NULL;
+       /*
+        * Truncate inode.  The only stuff left
+        * in the directory is "." and "..".  The
+        * "." reference is inconsequential since
+        * we're quashing it.  The ".." reference
+        * has already been adjusted above.  We've
+        * removed the "." reference and the reference
+        * in the parent directory, but there may be
+        * other hard links so decrement by 2 and
+        * worry about them later.
+        */
+       ip->i_nlink -= 2;
+       itrunc(ip, (u_long)0);
+out:
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+struct file *
+getinode(fdes)
+       int fdes;
+{
+       register struct file *fp;
+
+       fp = getf(fdes);
+       if (fp == 0)
+               return (0);
+       if (fp->f_type != DTYPE_INODE) {
+               u.u_error = EINVAL;
+               return (0);
+       }
+       return (fp);
+}
+
+/*
+ * mode mask for creation of files
+ */
+umask()
+{
+       register struct a {
+               int     mask;
+       } *uap;
+
+       uap = (struct a *)u.u_ap;
+       u.u_r.r_val1 = u.u_cmask;
+       u.u_cmask = uap->mask & 07777;
+}
index b6bbad2..a3fdf59 100644 (file)
@@ -1,4 +1,4 @@
-/*     ufs_vnops.c     4.56    83/05/21        */
+/*     ufs_vnops.c     4.57    83/05/27        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
 #include "../h/buf.h"
 #include "../h/proc.h"
 #include "../h/quota.h"
-#include "../h/descrip.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
 #include "../h/uio.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/nami.h"
+#include "../h/mount.h"
+
+extern struct fileops inodeops;
+struct file *getinode();
 
 /*
  * Change current working directory (``.'').
 
 /*
  * Change current working directory (``.'').
@@ -72,76 +75,74 @@ bad:
  */
 open()
 {
  */
 open()
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                char    *fname;
-               int     flags;
                int     mode;
                int     mode;
-       } *uap;
-       int checkpermissions = 1, flags;
+               int     crtmode;
+       } *uap = (struct a *) u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       flags = uap->flags + 1;
-       if ((flags&FTRUNCATE) && (flags&FWRITE) == 0) {
-               u.u_error = EINVAL;
-               return;
-       }
-       if (flags&FCREATE) {
-               ip = namei(uchar, CREATE, 1);
-               if (ip == NULL) {
-                       if (u.u_error)
-                               return;
-                       ip = maknode(uap->mode&07777&(~ISVTX));
-                       checkpermissions = 0;
-                       flags &= ~FTRUNCATE;
-               }
-       } else
-               ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       open1(ip, flags, checkpermissions);
+       copen(uap->mode-FOPEN, uap->crtmode);
 }
 
 }
 
-#ifndef NOCOMPAT
 /*
  * Creat system call.
  */
 /*
  * Creat system call.
  */
-ocreat()
+creat()
 {
 {
-       register struct inode *ip;
-       register struct a {
+       struct a {
                char    *fname;
                int     fmode;
                char    *fname;
                int     fmode;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, CREATE, 1);
-       if (ip == NULL) {
-               if (u.u_error)
-                       return;
-               ip = maknode(uap->fmode&07777&(~ISVTX));
-               if (ip == NULL)
-                       return;
-               open1(ip, FWRITE, 0);
-       } else
-               open1(ip, FWRITE|FTRUNCATE, 1);
+       copen(FWRITE|FCREAT|FTRUNC, uap->fmode);
 }
 }
-#endif
 
 /*
  * Common code for open and creat.
 
 /*
  * Common code for open and creat.
- * Check permissions (if we haven't done so already),
- * allocate an open file structure, and call
- * the device open routine, if any.
+ * Check permissions, allocate an open file structure,
+ * and call the device open routine if any.
  */
  */
-open1(ip, mode, checkpermissions)
-       register struct inode *ip;
-       register mode;
+copen(mode, arg)
+       register int mode;
+       int arg;
 {
 {
+       register struct inode *ip;
        register struct file *fp;
        register struct file *fp;
-       int i, flags;
+       int i;
 
 
-       if (checkpermissions) {
+#ifdef notdef
+       if ((mode&(FREAD|FWRITE)) == 0) {
+               u.u_error = EINVAL;
+               return;
+       }
+#endif
+       if (mode&FCREAT) {
+               ip = namei(uchar, CREATE, 1);
+               if (ip == NULL) {
+                       if (u.u_error)
+                               return;
+                       ip = maknode(arg&07777&(~ISVTX));
+                       if (ip == NULL)
+                               return;
+                       mode &= ~FTRUNC;
+               } else {
+                       if (mode&FEXCL) {
+                               u.u_error = EEXIST;
+                               iput(ip);
+                               return;
+                       }
+                       mode &= ~FCREAT;
+               }
+       } else {
+               ip = namei(uchar, LOOKUP, 1);
+               if (ip == NULL)
+                       return;
+       }
+       if ((ip->i_mode & IFMT) == IFSOCK) {
+               u.u_error = EOPNOTSUPP;
+               goto bad;
+       }
+       if ((mode&FCREAT) == 0) {
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
                if (mode&FREAD)
                        if (access(ip, IREAD))
                                goto bad;
@@ -154,36 +155,31 @@ open1(ip, mode, checkpermissions)
                        }
                }
        }
                        }
                }
        }
-
-       /*
-        * Check locking on inode.  Release "inode lock"
-        * while doing so in case we block inside flocki.
-        */
-       flags = 0;
-       if (mode&(FSHLOCK|FEXLOCK)) {
-               iunlock(ip);
-               flags = flocki(ip, 0, mode);
-               ilock(ip);
-               if (u.u_error)
-                       goto bad;
-       }
-       if (mode&FTRUNCATE)
+       fp = falloc();
+       if (fp == NULL)
+               goto bad;
+       if (mode&FTRUNC)
                itrunc(ip, (u_long)0);
        iunlock(ip);
                itrunc(ip, (u_long)0);
        iunlock(ip);
-       if ((fp = falloc()) == NULL)
-               goto out;
-       fp->f_flag = mode & FMODES;
-       fp->f_type = DTYPE_FILE;
+       fp->f_flag = mode&FMASK;
+       fp->f_type = DTYPE_INODE;
+       fp->f_ops = &inodeops;
+       fp->f_data = (caddr_t)ip;
        i = u.u_r.r_val1;
        i = u.u_r.r_val1;
-       fp->f_inode = ip;
-       u.u_error = openi(ip, mode);
-       if (u.u_error == 0) {
-               u.u_pofile[i] = flags;
+#ifdef notdef
+       if (setjmp(&u.u_qsave)) {
+               if (u.u_error == 0)
+                       u.u_error = EINTR;
+               u.u_ofile[i] = NULL;
+               closef(fp);
                return;
        }
                return;
        }
+#endif
+       u.u_error = openi(ip, mode);
+       if (u.u_error == 0)
+               return;
        u.u_ofile[i] = NULL;
        fp->f_count--;
        u.u_ofile[i] = NULL;
        fp->f_count--;
-out:
        irele(ip);
        return;
 bad:
        irele(ip);
        return;
 bad:
@@ -203,25 +199,30 @@ mknod()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       if (suser()) {
-               ip = namei(uchar, CREATE, 0);
-               if (ip != NULL) {
-                       u.u_error = EEXIST;
-                       goto out;
-               }
+       if (!suser())
+               return;
+       ip = namei(uchar, CREATE, 0);
+       if (ip != NULL) {
+               u.u_error = EEXIST;
+               goto out;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
        }
        if (u.u_error)
                return;
        ip = maknode(uap->fmode);
        if (ip == NULL)
                return;
-       if (uap->dev) {
-               /*
-                * Want to be able to use this to make badblock
-                * inodes, so don't truncate the dev number.
-                */
-               ip->i_rdev = uap->dev;
-               ip->i_flag |= IACC|IUPD|ICHG;
+       switch (ip->i_mode & IFMT) {
+
+       case IFCHR:
+       case IFBLK:
+               if (uap->dev) {
+                       /*
+                        * Want to be able to use this to make badblock
+                        * inodes, so don't truncate the dev number.
+                        */
+                       ip->i_rdev = uap->dev;
+                       ip->i_flag |= IACC|IUPD|ICHG;
+               }
        }
 
 out:
        }
 
 out:
@@ -367,17 +368,13 @@ lseek()
        } *uap;
 
        uap = (struct a *)u.u_ap;
        } *uap;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = ESPIPE;
-               return;
-       }
-       if (uap->sbase == FSEEK_RELATIVE)
+       if (uap->sbase == L_INCR)
                uap->off += fp->f_offset;
                uap->off += fp->f_offset;
-       else if (uap->sbase == FSEEK_EOF)
-               uap->off += fp->f_inode->i_size;
+       else if (uap->sbase == L_XTND)
+               uap->off += ((struct inode *)fp->f_data)->i_size;
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
        fp->f_offset = uap->off;
        u.u_r.r_off = uap->off;
 }
@@ -401,11 +398,11 @@ saccess()
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
        u.u_gid = u.u_rgid;
        ip = namei(uchar, LOOKUP, 1);
        if (ip != NULL) {
-               if ((uap->fmode&FACCESS_READ) && access(ip, IREAD))
+               if ((uap->fmode&R_OK) && access(ip, IREAD))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_WRITE) && access(ip, IWRITE))
+               if ((uap->fmode&W_OK) && access(ip, IWRITE))
                        goto done;
                        goto done;
-               if ((uap->fmode&FACCESS_EXECUTE) && access(ip, IEXEC))
+               if ((uap->fmode&X_OK) && access(ip, IEXEC))
                        goto done;
 done:
                iput(ip);
                        goto done;
 done:
                iput(ip);
@@ -414,103 +411,41 @@ done:
        u.u_gid = svgid;
 }
 
        u.u_gid = svgid;
 }
 
-/*
- * the fstat system call.
- */
-fstat()
-{
-       register struct file *fp;
-       register struct a {
-               int     fd;
-               struct stat *sb;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
-       if (fp == NULL)
-               return;
-       if (fp->f_type == DTYPE_SOCKET)
-               u.u_error = sostat(fp->f_socket, uap->sb);
-       else
-               stat1(fp->f_inode, uap->sb);
-}
-
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
 /*
  * Stat system call.  This version follows links.
  */
 stat()
 {
-       register struct inode *ip;
-       register struct a {
-               char    *fname;
-               struct stat *sb;
-       } *uap;
 
 
-       uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 1);
-       if (ip == NULL)
-               return;
-       stat1(ip, uap->sb);
-       iput(ip);
+       stat1(1);
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
 }
 
 /*
  * Lstat system call.  This version does not follow links.
  */
 lstat()
+{
+
+       stat1(0);
+}
+
+stat1(follow)
+       int follow;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
 {
        register struct inode *ip;
        register struct a {
                char    *fname;
-               struct stat *sb;
+               struct stat *ub;
        } *uap;
        } *uap;
+       struct stat sb;
 
        uap = (struct a *)u.u_ap;
 
        uap = (struct a *)u.u_ap;
-       ip = namei(uchar, LOOKUP, 0);
+       ip = namei(uchar, LOOKUP, follow);
        if (ip == NULL)
                return;
        if (ip == NULL)
                return;
-       stat1(ip, uap->sb);
+       (void) statinode(ip, &sb);
        iput(ip);
        iput(ip);
-}
-
-/*
- * The basic routine for fstat and stat:
- * get the inode and pass appropriate parts back.
- */
-stat1(ip, ub)
-       register struct inode *ip;
-       struct stat *ub;
-{
-       struct stat ds;
-
-       IUPDAT(ip, &time, &time, 0);
-       /*
-        * Copy from inode table
-        */
-       ds.st_dev = ip->i_dev;
-       ds.st_ino = ip->i_number;
-       ds.st_mode = ip->i_mode;
-       ds.st_nlink = ip->i_nlink;
-       ds.st_uid = ip->i_uid;
-       ds.st_gid = ip->i_gid;
-       ds.st_rdev = (dev_t)ip->i_rdev;
-       ds.st_size = ip->i_size;
-       ds.st_atime = ip->i_atime;
-       ds.st_spare1 = 0;
-       ds.st_mtime = ip->i_mtime;
-       ds.st_spare2 = 0;
-       ds.st_ctime = ip->i_ctime;
-       ds.st_spare3 = 0;
-       /* this doesn't belong here */
-       if ((ip->i_mode&IFMT) == IFBLK)
-               ds.st_blksize = BLKDEV_IOSIZE;
-       else if ((ip->i_mode&IFMT) == IFCHR)
-               ds.st_blksize = MAXBSIZE;
-       else
-               ds.st_blksize = ip->i_fs->fs_bsize;
-       ds.st_blocks = ip->i_blocks;
-       ds.st_spare4[0] = ds.st_spare4[1] = 0;
-       u.u_error = copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds));
+       u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
 }
 
 /*
 }
 
 /*
@@ -570,14 +505,10 @@ fchmod()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
        if (u.u_uid != ip->i_uid && !suser())
                return;
        ilock(ip);
@@ -593,7 +524,6 @@ chmod1(ip, mode)
        register struct inode *ip;
        register int mode;
 {
        register struct inode *ip;
        register int mode;
 {
-       register int *gp;
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
 
        ip->i_mode &= ~07777;
        if (u.u_uid) {
@@ -640,14 +570,10 @@ fchown()
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
        register struct file *fp;
 
        uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        if (!suser())
                return;
        ilock(ip);
        if (!suser())
                return;
        ilock(ip);
@@ -756,29 +682,24 @@ sync()
  */
 flock()
 {
  */
 flock()
 {
-       struct a {
+       register struct a {
                int     fd;
                int     how;
                int     fd;
                int     how;
-       } *uap;
+       } *uap = (struct a *)u.u_ap;
        register struct file *fp;
        register int cmd, flags;
 
        register struct file *fp;
        register int cmd, flags;
 
-       uap = (struct a *)u.u_ap;
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {               /* XXX */
-               u.u_error = EINVAL;
-               return;
-       }
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
        cmd = uap->how;
        flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK);
-       if (cmd&FUNLOCK) {
+       if (cmd&LOCK_UN) {
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
                if (flags == 0) {
                        u.u_error = EINVAL;
                        return;
                }
-               funlocki(fp->f_inode, flags);
+               funlocki((struct inode *)fp->f_data, flags);
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
                u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK);
                return;
        }
@@ -786,10 +707,11 @@ flock()
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
         * No reason to write lock a file we've already
         * write locked, similarly with a read lock.
         */
-       if ((flags&UF_EXLOCK) && (cmd&FEXLOCK) ||
-           (flags&UF_SHLOCK) && (cmd&FSHLOCK))
+       if ((flags&UF_EXLOCK) && (cmd&LOCK_EX) ||
+           (flags&UF_SHLOCK) && (cmd&LOCK_SH))
                return;
                return;
-       u.u_pofile[uap->fd] = flocki(fp->f_inode, u.u_pofile[uap->fd], cmd);
+       u.u_pofile[uap->fd] =
+           flocki((struct inode *)fp->f_data, u.u_pofile[uap->fd], cmd);
 }
 
 /*
 }
 
 /*
@@ -829,18 +751,14 @@ ftruncate()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
        if ((fp->f_flag&FWRITE) == 0) {
                u.u_error = EINVAL;
                return;
        }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
        ilock(ip);
        itrunc(ip, uap->length);
        iunlock(ip);
@@ -857,14 +775,10 @@ fsync()
        struct inode *ip;
        struct file *fp;
 
        struct inode *ip;
        struct file *fp;
 
-       fp = getf(uap->fd);
+       fp = getinode(uap->fd);
        if (fp == NULL)
                return;
        if (fp == NULL)
                return;
-       if (fp->f_type == DTYPE_SOCKET) {
-               u.u_error = EINVAL;
-               return;
-       }
-       ip = fp->f_inode;
+       ip = (struct inode *)fp->f_data;
        ilock(ip);
        syncip(ip);
        iunlock(ip);
        ilock(ip);
        syncip(ip);
        iunlock(ip);
@@ -1198,3 +1112,220 @@ maknode(mode)
        }
        return (ip);
 }
        }
        return (ip);
 }
+
+/*
+ * A virgin directory (no blushing please).
+ */
+struct dirtemplate mastertemplate = {
+       0, 12, 1, ".",
+       0, DIRBLKSIZ - 12, 2, ".."
+};
+
+/*
+ * Mkdir system call
+ */
+mkdir()
+{
+       struct a {
+               char    *name;
+               int     dmode;
+       } *uap;
+       register struct inode *ip, *dp;
+       struct dirtemplate dirtemplate;
+
+       uap = (struct a *)u.u_ap;
+       ip = namei(uchar, CREATE, 0);
+       if (u.u_error)
+               return;
+       if (ip != NULL) {
+               iput(ip);
+               u.u_error = EEXIST;
+               return;
+       }
+       dp = u.u_pdir;
+       uap->dmode &= 0777;
+       uap->dmode |= IFDIR;
+       /*
+        * Must simulate part of maknode here
+        * in order to acquire the inode, but
+        * not have it entered in the parent
+        * directory.  The entry is made later
+        * after writing "." and ".." entries out.
+        */
+       ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode);
+       if (ip == NULL) {
+               iput(dp);
+               return;
+       }
+#ifdef QUOTA
+       if (ip->i_dquot != NODQUOT)
+               panic("mkdir: dquot");
+#endif
+       ip->i_flag |= IACC|IUPD|ICHG;
+       ip->i_mode = uap->dmode & ~u.u_cmask;
+       ip->i_nlink = 2;
+       ip->i_uid = u.u_uid;
+       ip->i_gid = dp->i_gid;
+#ifdef QUOTA
+       ip->i_dquot = inoquota(ip);
+#endif
+       iupdat(ip, &time, &time, 1);
+
+       /*
+        * Bump link count in parent directory
+        * to reflect work done below.  Should
+        * be done before reference is created
+        * so reparation is possible if we crash.
+        */
+       dp->i_nlink++;
+       dp->i_flag |= ICHG;
+       iupdat(dp, &time, &time, 1);
+
+       /*
+        * Initialize directory with "."
+        * and ".." from static template.
+        */
+       dirtemplate = mastertemplate;
+       dirtemplate.dot_ino = ip->i_number;
+       dirtemplate.dotdot_ino = dp->i_number;
+       u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate,
+               sizeof (dirtemplate), (off_t)0, 1, (int *)0);
+       if (u.u_error) {
+               dp->i_nlink--;
+               dp->i_flag |= ICHG;
+               goto bad;
+       }
+       /*
+        * Directory all set up, now
+        * install the entry for it in
+        * the parent directory.
+        */
+       u.u_error = direnter(ip);
+       dp = NULL;
+       if (u.u_error) {
+               u.u_dirp = uap->name;
+               dp = namei(uchar, LOOKUP, 0);
+               if (dp) {
+                       dp->i_nlink--;
+                       dp->i_flag |= ICHG;
+               }
+       }
+bad:
+       /*
+        * No need to do an explicit itrunc here,
+        * irele will do this for us because we set
+        * the link count to 0.
+        */
+       if (u.u_error) {
+               ip->i_nlink = 0;
+               ip->i_flag |= ICHG;
+       }
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+/*
+ * Rmdir system call.
+ */
+rmdir()
+{
+       struct a {
+               char    *name;
+       };
+       register struct inode *ip, *dp;
+
+       ip = namei(uchar, DELETE | LOCKPARENT, 0);
+       if (ip == NULL)
+               return;
+       dp = u.u_pdir;
+       /*
+        * No rmdir "." please.
+        */
+       if (dp == ip) {
+               irele(dp);
+               iput(ip);
+               u.u_error = EINVAL;
+               return;
+       }
+       if ((ip->i_mode&IFMT) != IFDIR) {
+               u.u_error = ENOTDIR;
+               goto out;
+       }
+       /*
+        * Don't remove a mounted on directory.
+        */
+       if (ip->i_dev != dp->i_dev) {
+               u.u_error = EBUSY;
+               goto out;
+       }
+       /*
+        * Verify the directory is empty (and valid).
+        * (Rmdir ".." won't be valid since
+        *  ".." will contain a reference to
+        *  the current directory and thus be
+        *  non-empty.)
+        */
+       if (ip->i_nlink != 2 || !dirempty(ip)) {
+               u.u_error = ENOTEMPTY;
+               goto out;
+       }
+       /*
+        * Delete reference to directory before purging
+        * inode.  If we crash in between, the directory
+        * will be reattached to lost+found,
+        */
+       if (dirremove() == 0)
+               goto out;
+       dp->i_nlink--;
+       dp->i_flag |= ICHG;
+       iput(dp);
+       dp = NULL;
+       /*
+        * Truncate inode.  The only stuff left
+        * in the directory is "." and "..".  The
+        * "." reference is inconsequential since
+        * we're quashing it.  The ".." reference
+        * has already been adjusted above.  We've
+        * removed the "." reference and the reference
+        * in the parent directory, but there may be
+        * other hard links so decrement by 2 and
+        * worry about them later.
+        */
+       ip->i_nlink -= 2;
+       itrunc(ip, (u_long)0);
+out:
+       if (dp)
+               iput(dp);
+       iput(ip);
+}
+
+struct file *
+getinode(fdes)
+       int fdes;
+{
+       register struct file *fp;
+
+       fp = getf(fdes);
+       if (fp == 0)
+               return (0);
+       if (fp->f_type != DTYPE_INODE) {
+               u.u_error = EINVAL;
+               return (0);
+       }
+       return (fp);
+}
+
+/*
+ * mode mask for creation of files
+ */
+umask()
+{
+       register struct a {
+               int     mask;
+       } *uap;
+
+       uap = (struct a *)u.u_ap;
+       u.u_r.r_val1 = u.u_cmask;
+       u.u_cmask = uap->mask & 07777;
+}