update from Rick Macklem to generate proper error messages
[unix-history] / usr / src / sys / kern / sys_socket.c
index 335710c..97864cd 100644 (file)
@@ -1,35 +1,61 @@
-/*     sys_socket.c    4.1     83/05/27        */
-
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/file.h"
-#include "../h/mbuf.h"
-#include "../h/protosw.h"
-#include "../h/socket.h"
-#include "../h/socketvar.h"
-#include "../h/ioctl.h"
-#include "../h/uio.h"
-#include "../h/stat.h"
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)sys_socket.c        7.5 (Berkeley) %G%
+ */
+
+#include "param.h"
+#include "systm.h"
+#include "user.h"
+#include "file.h"
+#include "mbuf.h"
+#include "protosw.h"
+#include "socket.h"
+#include "socketvar.h"
+#include "ioctl.h"
+#include "uio.h"
+#include "stat.h"
 
 #include "../net/if.h"
 #include "../net/route.h"
 
 
 #include "../net/if.h"
 #include "../net/route.h"
 
-int    soo_rw(), soo_ioctl(), soo_select(), soo_stat(), soo_close();
+int    soo_read(), soo_write(), soo_ioctl(), soo_select(), soo_close();
 struct fileops socketops =
 struct fileops socketops =
-    { soo_rw, soo_ioctl, soo_select, soo_stat, soo_close };
+    { soo_read, soo_write, soo_ioctl, soo_select, soo_close };
 
 
-soo_rw(fp, rw, uio)
+/* ARGSUSED */
+soo_read(fp, uio, cred)
        struct file *fp;
        struct file *fp;
-       enum uio_rw rw;
        struct uio *uio;
        struct uio *uio;
+       struct ucred *cred;
 {
 {
-       int soreceive(), sosend();
 
 
-       return (
-           (*(rw==UIO_READ?soreceive:sosend))
-             ((struct socket *)fp->f_data, 0, uio, 0, 0));
+       return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0,
+               uio, (int *)0, (struct mbuf **)0, (struct mbuf **)0));
+}
+
+/* ARGSUSED */
+soo_write(fp, uio, cred)
+       struct file *fp;
+       struct uio *uio;
+       struct ucred *cred;
+{
+
+       return (sosend((struct socket *)fp->f_data, (struct mbuf *)0,
+               uio, 0, (struct mbuf *)0, (struct mbuf *)0));
 }
 
 soo_ioctl(fp, cmd, data)
 }
 
 soo_ioctl(fp, cmd, data)
@@ -46,55 +72,43 @@ soo_ioctl(fp, cmd, data)
                        so->so_state |= SS_NBIO;
                else
                        so->so_state &= ~SS_NBIO;
                        so->so_state |= SS_NBIO;
                else
                        so->so_state &= ~SS_NBIO;
-               break;
+               return (0);
 
        case FIOASYNC:
                if (*(int *)data)
                        so->so_state |= SS_ASYNC;
                else
                        so->so_state &= ~SS_ASYNC;
 
        case FIOASYNC:
                if (*(int *)data)
                        so->so_state |= SS_ASYNC;
                else
                        so->so_state &= ~SS_ASYNC;
-               break;
+               return (0);
+
+       case FIONREAD:
+               *(int *)data = so->so_rcv.sb_cc;
+               return (0);
 
        case SIOCSPGRP:
 
        case SIOCSPGRP:
-               so->so_pgrp = *(int *)data;
-               break;
+               so->so_pgid = *(int *)data;
+               return (0);
 
        case SIOCGPGRP:
 
        case SIOCGPGRP:
-               *(int *)data = so->so_pgrp;
-               break;
+               *(int *)data = so->so_pgid;
+               return (0);
 
        case SIOCATMARK:
                *(int *)data = (so->so_state&SS_RCVATMARK) != 0;
 
        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);
        }
        }
-       return (0);
+       /*
+        * Interface/routing/protocol specific ioctls:
+        * interface and routing ioctls should have a
+        * different entry since a socket's unnecessary
+        */
+#define        cmdbyte(x)      (((x) >> 8) & 0xff)
+       if (cmdbyte(cmd) == 'i')
+               return (ifioctl(so, cmd, data));
+       if (cmdbyte(cmd) == 'r')
+               return (rtioctl(cmd, data));
+       return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 
+           (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
 }
 
 soo_select(fp, which)
 }
 
 soo_select(fp, which)
@@ -121,31 +135,39 @@ soo_select(fp, which)
                }
                sbselqueue(&so->so_snd);
                break;
                }
                sbselqueue(&so->so_snd);
                break;
+
+       case 0:
+               if (so->so_oobmark ||
+                   (so->so_state & SS_RCVATMARK)) {
+                       splx(s);
+                       return (1);
+               }
+               sbselqueue(&so->so_rcv);
+               break;
        }
        splx(s);
        return (0);
 }
 
        }
        splx(s);
        return (0);
 }
 
-soo_stat(fp, ub)
-       struct file *fp;
+/*ARGSUSED*/
+soo_stat(so, ub)
+       register struct socket *so;
        register struct stat *ub;
 {
        register struct stat *ub;
 {
-       register struct socket *so = (struct socket *)fp->f_data;
 
        bzero((caddr_t)ub, sizeof (*ub));
 
        bzero((caddr_t)ub, sizeof (*ub));
-#ifdef notdef
        return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
            (struct mbuf *)ub, (struct mbuf *)0, 
            (struct mbuf *)0));
        return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
            (struct mbuf *)ub, (struct mbuf *)0, 
            (struct mbuf *)0));
-#endif
-       return (0);
 }
 
 soo_close(fp)
        struct file *fp;
 {
 }
 
 soo_close(fp)
        struct file *fp;
 {
-       int error = soclose((struct socket *)fp->f_data);
+       int error = 0;
 
 
+       if (fp->f_data)
+               error = soclose((struct socket *)fp->f_data);
        fp->f_data = 0;
        return (error);
 }
        fp->f_data = 0;
        return (error);
 }