BSD 4_3_Tahoe release
[unix-history] / usr / src / sys / sys / sys_generic.c
index fa3a2d6..a538a41 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
- *     @(#)sys_generic.c       7.1 (Berkeley) 6/5/86
+ *     @(#)sys_generic.c       7.7 (Berkeley) 5/24/88
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -16,6 +16,7 @@
 #include "uio.h"
 #include "kernel.h"
 #include "stat.h"
 #include "uio.h"
 #include "kernel.h"
 #include "stat.h"
+#include "malloc.h"
 
 /*
  * Read system call.
 
 /*
  * Read system call.
@@ -135,7 +136,6 @@ rwuio(uio, rw)
                iov++;
        }
        count = uio->uio_resid;
                iov++;
        }
        count = uio->uio_resid;
-       uio->uio_offset = fp->f_offset;
        if (setjmp(&u.u_qsave)) {
                if (uio->uio_resid == count) {
                        if ((u.u_sigintr & sigmask(u.u_procp->p_cursig)) != 0)
        if (setjmp(&u.u_qsave)) {
                if (uio->uio_resid == count) {
                        if ((u.u_sigintr & sigmask(u.u_procp->p_cursig)) != 0)
@@ -146,7 +146,6 @@ rwuio(uio, rw)
        } else
                u.u_error = (*fp->f_ops->fo_rw)(fp, rw, uio);
        u.u_r.r_val1 = count - uio->uio_resid;
        } else
                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;
 }
 
 /*
 }
 
 /*
@@ -162,7 +161,10 @@ ioctl()
        } *uap;
        register int com;
        register u_int size;
        } *uap;
        register int com;
        register u_int size;
-       char data[IOCPARM_MASK+1];
+       caddr_t memp = 0;
+#define STK_PARAMS     128
+       char stkbuf[STK_PARAMS];
+       caddr_t data = stkbuf;
 
        uap = (struct a *)u.u_ap;
        GETF(fp, uap->fdes);
 
        uap = (struct a *)u.u_ap;
        GETF(fp, uap->fdes);
@@ -199,17 +201,25 @@ ioctl()
         * amount of data to be copied to/from the
         * user's address space.
         */
         * amount of data to be copied to/from the
         * user's address space.
         */
-       size = (com &~ (IOC_INOUT|IOC_VOID)) >> 16;
-       if (size > sizeof (data)) {
+       size = IOCPARM_LEN(com);
+       if (size > IOCPARM_MAX) {
                u.u_error = EFAULT;
                return;
        }
                u.u_error = EFAULT;
                return;
        }
+       if (size > sizeof (stkbuf)) {
+               memp = (caddr_t)malloc((u_long)IOCPARM_MAX, M_IOCTLOPS,
+                   M_WAITOK);
+               data = memp;
+       }
        if (com&IOC_IN) {
                if (size) {
                        u.u_error =
        if (com&IOC_IN) {
                if (size) {
                        u.u_error =
-                           copyin(uap->cmarg, (caddr_t)data, (u_int)size);
-                       if (u.u_error)
+                           copyin(uap->cmarg, data, (u_int)size);
+                       if (u.u_error) {
+                               if (memp)
+                                       free(memp, M_IOCTLOPS);
                                return;
                                return;
+                       }
                } else
                        *(caddr_t *)data = uap->cmarg;
        } else if ((com&IOC_OUT) && size)
                } else
                        *(caddr_t *)data = uap->cmarg;
        } else if ((com&IOC_OUT) && size)
@@ -217,7 +227,7 @@ ioctl()
                 * Zero the buffer on the stack so the user
                 * always gets back something deterministic.
                 */
                 * Zero the buffer on the stack so the user
                 * always gets back something deterministic.
                 */
-               bzero((caddr_t)data, size);
+               bzero(data, size);
        else if (com&IOC_VOID)
                *(caddr_t *)data = uap->cmarg;
 
        else if (com&IOC_VOID)
                *(caddr_t *)data = uap->cmarg;
 
@@ -225,27 +235,34 @@ ioctl()
 
        case FIONBIO:
                u.u_error = fset(fp, FNDELAY, *(int *)data);
 
        case FIONBIO:
                u.u_error = fset(fp, FNDELAY, *(int *)data);
-               return;
+               break;
 
        case FIOASYNC:
                u.u_error = fset(fp, FASYNC, *(int *)data);
 
        case FIOASYNC:
                u.u_error = fset(fp, FASYNC, *(int *)data);
-               return;
+               break;
 
        case FIOSETOWN:
                u.u_error = fsetown(fp, *(int *)data);
 
        case FIOSETOWN:
                u.u_error = fsetown(fp, *(int *)data);
-               return;
+               break;
 
        case FIOGETOWN:
                u.u_error = fgetown(fp, (int *)data);
 
        case FIOGETOWN:
                u.u_error = fgetown(fp, (int *)data);
-               return;
+               break;
+       default:
+               if (setjmp(&u.u_qsave))
+                       u.u_error = EINTR;
+               else
+                       u.u_error = (*fp->f_ops->fo_ioctl)(fp, com, data);
+               /*
+                * Copy any data to user, size was
+                * already set and checked above.
+                */
+               if (u.u_error == 0 && (com&IOC_OUT) && size)
+                       u.u_error = copyout(data, uap->cmarg, (u_int)size);
+               break;
        }
        }
-       u.u_error = (*fp->f_ops->fo_ioctl)(fp, com, data);
-       /*
-        * Copy any data to user, size was
-        * already set and checked above.
-        */
-       if (u.u_error == 0 && (com&IOC_OUT) && size)
-               u.u_error = copyout(data, uap->cmarg, (u_int)size);
+       if (memp)
+               free(memp, M_IOCTLOPS);
 }
 
 int    unselect();
 }
 
 int    unselect();
@@ -309,7 +326,6 @@ retry:
                goto done;
        }
        if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) {
                goto done;
        }
        if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) {
-               u.u_procp->p_flag &= ~SSEL;
                splx(s);
                goto retry;
        }
                splx(s);
                goto retry;
        }
@@ -332,6 +348,7 @@ retry:
        splx(s);
        goto retry;
 done:
        splx(s);
        goto retry;
 done:
+       u.u_procp->p_flag &= ~SSEL;
 #define        putbits(name, x) \
        if (uap->name) { \
                int error = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \
 #define        putbits(name, x) \
        if (uap->name) { \
                int error = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \