From cc15ab5de52906ef195c43e5c5f271c97f4a8b0a Mon Sep 17 00:00:00 2001 From: Bill Joy Date: Sun, 15 Nov 1981 00:44:12 -0800 Subject: [PATCH] before header overlay SCCS-vsn: sys/kern/vfs_vnops.c 4.15 SCCS-vsn: sys/kern/uipc_syscalls.c 4.2 SCCS-vsn: sys/vax/vax/machdep.c 4.45 SCCS-vsn: sys/kern/init_main.c 4.20 SCCS-vsn: sys/kern/uipc_mbuf.c 1.9 SCCS-vsn: sys/conf/param.c 4.10 SCCS-vsn: sys/kern/uipc_proto.c 4.3 SCCS-vsn: sys/kern/uipc_socket.c 4.3 SCCS-vsn: sys/kern/vfs_syscalls.c 4.13 SCCS-vsn: sys/ufs/ffs/ffs_vnops.c 4.13 SCCS-vsn: sys/ufs/ffs/ufs_vnops.c 4.13 SCCS-vsn: sys/ufs/lfs/lfs_vnops.c 4.13 SCCS-vsn: sys/ufs/ufs/ufs_vnops.c 4.13 --- usr/src/sys/conf/param.c | 16 +- usr/src/sys/kern/init_main.c | 4 +- usr/src/sys/kern/uipc_mbuf.c | 17 +- usr/src/sys/kern/uipc_proto.c | 203 ++++------- usr/src/sys/kern/uipc_socket.c | 562 ++++++++++++------------------- usr/src/sys/kern/uipc_syscalls.c | 264 +++++++++------ usr/src/sys/kern/vfs_syscalls.c | 4 +- usr/src/sys/kern/vfs_vnops.c | 4 +- usr/src/sys/ufs/ffs/ffs_vnops.c | 4 +- usr/src/sys/ufs/ffs/ufs_vnops.c | 4 +- usr/src/sys/ufs/lfs/lfs_vnops.c | 4 +- usr/src/sys/ufs/ufs/ufs_vnops.c | 4 +- usr/src/sys/vax/vax/machdep.c | 10 +- 13 files changed, 479 insertions(+), 621 deletions(-) diff --git a/usr/src/sys/conf/param.c b/usr/src/sys/conf/param.c index 47eb787255..dc82bf9fd5 100644 --- a/usr/src/sys/conf/param.c +++ b/usr/src/sys/conf/param.c @@ -1,12 +1,7 @@ -/* param.c 4.9 81/11/08 */ +/* param.c 4.10 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" -#ifdef INET -#include "../net/inet.h" -#include "../net/inet_systm.h" -#include "../net/imp.h" -#endif INET #include "../h/socket.h" #include "../h/dir.h" #include "../h/user.h" @@ -40,10 +35,6 @@ int ncallout = 16 + MAXUSERS; int nclist = 100 + 16 * MAXUSERS; int nport = NPROC / 2; int nmbpages = NMBPAGES; -#ifdef INET -int nnetcon = NCON; -int nhost = NHOST; -#endif INET /* * These are initialized at bootstrap time @@ -66,8 +57,3 @@ short *swsize; int *swpf; char *buffers; struct cmap *cmap, *ecmap; -#ifdef INET -struct host *host, *hostNHOST; -struct net_stat netstat; -struct impstat imp_stat; -#endif INET diff --git a/usr/src/sys/kern/init_main.c b/usr/src/sys/kern/init_main.c index a63d55684b..27973027a9 100644 --- a/usr/src/sys/kern/init_main.c +++ b/usr/src/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* init_main.c 4.19 81/11/08 */ +/* init_main.c 4.20 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" @@ -84,7 +84,7 @@ main(firstaddr) */ mbinit(); #ifdef INET - prinit(); + pfinit(); #endif ihinit(); bhinit(); diff --git a/usr/src/sys/kern/uipc_mbuf.c b/usr/src/sys/kern/uipc_mbuf.c index 0472721b36..9fe6ebaf87 100644 --- a/usr/src/sys/kern/uipc_mbuf.c +++ b/usr/src/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* uipc_mbuf.c 1.8 81/11/08 */ +/* uipc_mbuf.c 1.9 81/11/14 */ #include "../h/param.h" #include "../h/dir.h" @@ -40,6 +40,21 @@ COUNT(M_GET); return (m); } +struct mbuf * +m_getclr(canwait) + int canwait; +{ + register struct mbuf *m; + +COUNT(M_GETCLR); + m = m_get(m, canwait); + if (m == 0) + return (0); + m->m_off = MMINOFF; + bzero(mtod(m, caddr_t), MLEN); + return (m); +} + struct mbuf * m_free(m) struct mbuf *m; diff --git a/usr/src/sys/kern/uipc_proto.c b/usr/src/sys/kern/uipc_proto.c index 54820d9900..a2717be8ab 100644 --- a/usr/src/sys/kern/uipc_proto.c +++ b/usr/src/sys/kern/uipc_proto.c @@ -1,4 +1,4 @@ -/* uipc_proto.c 4.2 81/11/08 */ +/* uipc_proto.c 4.3 81/11/14 */ #include "../h/param.h" #include "../h/socket.h" @@ -7,164 +7,114 @@ #include "../h/mbuf.h" #include "../net/inet.h" -/* should include a header file giving desired protocols */ -#define NTCP 1 - /* * Protocol configuration table and routines to search it. + * + * SHOULD INCLUDE A HEADER FILE GIVING DESIRED PROTOCOLS */ /* - * Generic (local or not yet specified) protocol. + * Local protocol handler. */ -int gen_usrreq(); +int pi_usrreq(); -#if NTCP > 0 /* * TCP/IP protocol family: IP, ICMP, UDP, TCP. */ -int ip_init(),ip_input(),ip_output(),ip_advise(),ip_slowtimo(),ip_drain(); -int icmp_input(),icmp_drain(); -int udp_input(),udp_advise(),udp_usrreq(),udp_sense(); -int tcp_init(),tcp_input(),tcp_advise(),tcp_fasttimo(),tcp_slowtimo(), - tcp_usrreq(),tcp_drain(),tcp_sense(); -int ri_input(),ri_advise(),ri_usrreq(),ri_sense(); -#endif - -#if NPUP > 0 -/* - * Pup protocols: PUP, BSP. - */ -int pup1_input(),pup1_output(),pup1_advise(),pup1_slowtimo(), - pup1_drain(),pup1_usrreq(),pup1_sense(); -int bsp_input(),bsp_advise(),bsp_fasttimo(),bsp_slowtimo(), - bsp_drain(),bsp_usrreq(),bsp_sense(); -int rawpup_input(),rawpup_usrreq(),rawpup_sense(); -#endif - -#if NCHAOS > 0 -/* - * Chaosnet protocols. - */ -/* ... */ -#endif - -#if NOISCP > 0 -/* - * Office information system communcation protocols. - */ -/* ... */ -#endif - -#if NNBS > 0 -/* - * NBS protocols. - */ -/* ... */ -#endif - -#if NECMA > 0 -/* - * ECMA protocols. - */ -/* ... */ -#endif - -#if NDATAKIT > 0 -/* - * Datakit protocols. - */ -/* ... */ -#endif +int ip_input(),ip_output(),ip_ctloutput(); +int ip_init(),ip_slowtimo(),ip_drain(); +int icmp_input(); +int icmp_drain(); +int udp_input(),udp_ctlinput(); +int udp_usrreq(),udp_sense(); +int udp_init(); +int tcp_input(),tcp_ctlinput(); +int tcp_usrreq(),tcp_sense(); +int tcp_init(),tcp_fasttimo(),tcp_slowtimo(),tcp_drain(); +int ri_input(),ri_ctlinput(); +int ri_usrreq(),ri_sense(); struct protosw protosw[] = { -{ SOCK_STREAM, PF_GENERIC, 0, 0, +{ SOCK_STREAM, PF_LOCAL, 0, PR_CONNREQUIRED, 0, 0, 0, 0, - 0, 0, 0, gen_usrreq, 0, - 0 }, -{ SOCK_DGRAM, PF_GENERIC, 0, PR_ATOMIC|PR_ADDR, + pi_usrreq, 0, 0, 0, 0, 0, 0, - 0, 0, 0, gen_usrreq, 0, - 0 }, -{ SOCK_RDM, PF_GENERIC, 0, PR_ATOMIC|PR_ADDR, +}, +{ SOCK_DGRAM, PF_LOCAL, 0, PR_ATOMIC|PR_ADDR, 0, 0, 0, 0, - 0, 0, 0, gen_usrreq, 0, - 0 }, -{ SOCK_RAW, PF_GENERIC, 0, PR_ATOMIC|PR_ADDR, + pi_usrreq, 0, 0, 0, 0, 0, 0, - 0, 0, 0, gen_usrreq, 0, - 0 }, -#if NTCP > 0 +}, +{ SOCK_RDM, PF_LOCAL, 0, PR_ATOMIC|PR_ADDR, + 0, 0, 0, 0, + pi_usrreq, 0, 0, + 0, 0, 0, 0, +}, +{ SOCK_RAW, PF_LOCAL, 0, PR_ATOMIC|PR_ADDR, + 0, 0, 0, 0, + pi_usrreq, 0, 0, + 0, 0, 0, 0, +}, { 0, 0, 0, 0, - ip_init, ip_input, ip_output, 0, - 0, ip_slowtimo, ip_drain, 0, 0, - 0 }, + ip_input, ip_output, 0, 0, + 0, 0, 0, + ip_init, 0, ip_slowtimo, ip_drain, +}, { 0, 0, IPPROTO_ICMP, 0, - 0, icmp_input, 0, 0, - 0, 0, icmp_drain, 0, 0, - 0 }, + icmp_input, 0, 0, 0, + 0, 0, 0, + 0, 0, 0, icmp_drain, +}, { SOCK_DGRAM, PF_INET, IPPROTO_UDP, PR_ATOMIC|PR_ADDR, - 0, udp_input, 0, udp_advise, - 0, 0, 0, udp_usrreq, udp_sense, - MLEN }, -{ SOCK_STREAM, PF_INET, IPPROTO_TCP, 0, - tcp_init, tcp_input, 0, tcp_advise, - tcp_fasttimo, tcp_slowtimo, tcp_drain, tcp_usrreq, tcp_sense, - MLEN }, + udp_input, 0, udp_ctlinput, 0, + udp_usrreq, udp_sense, MLEN, + udp_init, 0, 0, 0, +}, +{ SOCK_STREAM, PF_INET, IPPROTO_TCP, PR_CONNREQUIRED, + tcp_input, 0, tcp_ctlinput, 0, + tcp_usrreq, tcp_sense, MLEN, + tcp_init, tcp_fasttimo, tcp_slowtimo, tcp_drain, +}, { SOCK_RAW, PF_INET, IPPROTO_RAW, PR_ATOMIC|PR_ADDR, - 0, ri_input, 0, ri_advise, - 0, 0, 0, ri_usrreq, ri_sense, - MLEN }, -#endif -#if NPUP > 0 -{ SOCK_DGRAM, PF_PUP, 0, PR_ATOMIC|PR_ADDR, - pup_init, pup_input, pup_output, pup_advise, - 0, pup_slowtimo, pup_drain, pup_usrreq, pup_sense, - MLEN }, -{ SOCK_STREAM, PF_PUP1, PUPPROTO_BSP, 0, - bsp_init, bsp_input, 0, bsp_advise, - bsp_fasttimo, bsp_slowtimo, bsp_drain, bsp_usrreq, bsp_sense, - MLEN }, -{ SOCK_RAW, PF_PUP1, PUPPROTO_RAW, PR_ATOMIC|PR_ADDR, - rp_init, rp_input, 0, rp_advise, - rp_fasttimo, rp_slowtimo, rp_drain, rp_usrreq, rp_sense, - MLEN }, -#endif -#if NCHAOS > 0 -/* ... */ -#endif -#if NOISCP > 0 -/* ... */ -#endif -#if NNBS > 0 -/* ... */ -#endif -#if NECMA > 0 -/* ... */ -#endif -#if NDATAKIT > 0 -/* ... */ -#endif + ri_input, 0, ri_ctlinput, 0, + ri_usrreq, ri_sense, MLEN, + 0, 0, 0, 0, +} }; -#define protoswEND &protosw[sizeof (protosw)/sizeof (protosw[0])] + +#define NPROTOSW (sizeof(protosw) / sizeof(protosw[0])) + +struct protosw *protoswLAST = &protosw[NPROTOSW-1]; /* * Operations on protocol table and protocol families. */ +/* + * Initialize all protocols. + */ +pfinit() +{ + register struct protosw *pr; + + for (pr = protoswLAST; pr >= protosw; pr--) + if (pr->pr_init) + (*pr->pr_init)(); +} + /* * Find a standard protocol in a protocol family * of a specific type. */ struct protosw * -pf_findtype(family, type) +pffindtype(family, type) int family, type; { register struct protosw *pr; if (family == 0) return (0); - for (pr = protosw; pr < protoswEND; pr++) + for (pr = protosw; pr < protoswLAST; pr++) if (pr->pr_family == family && pr->pr_type == type) return (pr); return (0); @@ -174,20 +124,15 @@ pf_findtype(family, type) * Find a specified protocol in a specified protocol family. */ struct protosw * -pf_findproto(family, protocol) +pffindproto(family, protocol) int family, protocol; { register struct protosw *pr; if (family == 0) return (0); - for (pr = protosw; pr < protoswEND; pr++) + for (pr = protosw; pr < protoswLAST; pr++) if (pr->pr_family == family && pr->pr_protocol == protocol) return (pr); return (0); } - -prinit() -{ - -} diff --git a/usr/src/sys/kern/uipc_socket.c b/usr/src/sys/kern/uipc_socket.c index 1428cc13b9..b06e669b0b 100644 --- a/usr/src/sys/kern/uipc_socket.c +++ b/usr/src/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* uipc_socket.c 4.2 81/11/08 */ +/* uipc_socket.c 4.3 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" @@ -17,42 +17,12 @@ #include "../net/inet.h" #include "../net/inet_systm.h" -struct socket zerosocket; -struct in_addr zeroin_addr; - /* - * Socket system call interface. Copy in arguments - * set up file descriptor and call internal socket - * creation routine. + * Socket support routines. + * + * DEAL WITH INTERRUPT NOTIFICATION. + * DO NEWFD STUFF */ -ssocket() -{ - register struct a { - int type; - struct in_addr *ain; - int options; - } *uap = (struct a *)u.u_ap; - struct in_addr in; - struct socket *so0; - register struct socket *so; - register struct file *fp; - - if ((fp = falloc()) == NULL) - return; - fp->f_flag = FSOCKET|FREAD|FWRITE; - if (copyin((caddr_t)uap->ain, &in, sizeof (in))) { - u.u_error = EFAULT; - return; - } - u.u_error = socket(&so0, uap->type, &in, uap->options); - if (u.u_error) - goto bad; - fp->f_socket = so; - return; -bad: - u.u_ofile[u.u_r.r_val1] = 0; - fp->f_count = 0; -} /* * Create a socket. @@ -66,377 +36,296 @@ socket(aso, type, iap, options) register struct protosw *prp; register struct socket *so; struct mbuf *m; - int pf, proto; + int pf, proto, error; /* - * Pin down protocol if possible. - * If no address specified, use a generic protocol. + * Use process standard protocol/protocol family if none + * specified by address argument. */ if (iap == 0) { - pf = PF_GENERIC; + pf = PF_INET; /* should be u.u_protof */ proto = 0; } else { pf = iap->ia_pf; proto = iap->ia_proto; } - if (proto) { - /* - * A specific protocol was requested. Look - * for the protocol. If not found, then we - * don't support it. - */ - prp = pf_findproto(pf, proto); - if (prp == 0) - return (EPROTONOSUPPORT); - } else { - /* - * No specific protocol was requested. Look - * in the specified (or generic) protocol set - * for a protocol of this type. - */ - prp = pf_findtype(pf, type); - if (prp == 0) - return (pf == PF_GENERIC ? - ESOCKTNOSUPPORT : EPROTONOSUPPORT); - } + + /* + * If protocol specified, look for it, otherwise + * for a protocol of the correct type in the right family. + */ + if (proto) + prp = pffindproto(pf, proto); + else + prp = pffindtype(pf, type); + if (prp == 0) + return (EPROTONOSUPPORT); /* * Get a socket structure. */ - m = m_get(M_WAIT); + m = m_getclr(M_WAIT); if (m == 0) return (ENOBUFS); - m->m_off = MMINOFF; so = mtod(m, struct socket *); - *so = zerosocket; so->so_options = options; /* - * An early call to protocol initialization. If protocol - * actually hasn't been decided on yet (till we know - * peer), then the generic protocol allocated so far can - * just make sure a reasonable amount of resources will - * be available to it (say by allocating liberally now - * and returning some of the resources later). + * Attach protocol to socket, initializing + * and reserving resources. */ so->so_proto = prp; (*prp->pr_usrreq)(so, PRU_ATTACH, 0, 0); if (so->so_error) { +/*###80 [cc] operands of = have incompatible types %%%*/ +/*###80 [cc] zerosocket undefined %%%*/ + error = so->so_error; m_free(dtom(so)); - return (u.u_error); + return (error); } *aso = so; return (0); } -spipe() -{ - -} - -skclose(so) - register struct socket *so; -{ - - if (so->so_pcb) - (*so->so_proto->pr_usrreq)(so, PRU_DETACH, 0, 0); -} - /* - * Select a socket. + * Close a socket on last file table reference removal. + * Initiate disconnect if connected. + * Free socket when disconnect complete. */ -soselect(so, flag) +soclose(so) register struct socket *so; - int flag; { - register struct proc *p; - - if (so->so_rcv.sb_cc) - return (1); - if ((p = so->so_rcv.sb_sel) && p->p_wchan == (caddr_t)select) - so->so_rcv.sb_flags |= SB_COLL; - else - so->so_rcv.sb_sel = u.u_procp; - return (0); + int s = splnet(); /* conservative */ + + if (so->so_pcb == 0) + goto discard; + if (so->so_state & SS_ISCONNECTED) { + if ((so->so_state & SS_ISDISCONNECTING) == 0) { + u.u_error = disconnect(so, 0); + if (u.u_error) { + splx(s); + return; + } + } + if ((so->so_state & SS_ISDISCONNECTING) && + (so->so_options & SO_NBIO)) { + u.u_error = EINPROGRESS; + splx(s); + return; + } + while (so->so_state & SS_ISCONNECTED) + sleep((caddr_t)&so->so_timeo, PZERO+1); + } + u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_DETACH, 0, 0); +discard: + if (so->so_pcb == 0) + sofree(so); + splx(s); } -/* - * Wakeup read sleep/select'ers. - */ -sowakeup(so) +sostat(so, sb) struct socket *so; + struct stat *sb; { - if (so->so_rcv.sb_cc && so->so_rcv.sb_sel) { - selwakeup(so->so_rcv.sb_sel, so->so_rcv.sb_flags & SB_COLL); - so->so_rcv.sb_sel = 0; - so->so_rcv.sb_flags &= ~SB_COLL; - } - if (so->so_rcv.sb_flags & SB_WAIT) { - so->so_rcv.sb_flags &= ~SB_WAIT; - wakeup((caddr_t)&so->so_rcv.sb_cc); - } + return (EOPNOTSUPP); } /* - * Connect socket to foreign peer; system call - * interface. Copy in arguments and call internal routine. + * Connect socket to a specified address. + * If already connected or connecting, then avoid + * the protocol entry, to keep its job simpler. */ -sconnect() -{ - register struct a { - int fdes; - struct in_addr *a; - } *uap = (struct a *)u.u_ap; - in_addr in; - register struct file *fp; - register struct socket *so; - int s; - - if (copyin((caddr_t)uap->a, &in, sizeof (in))) { - u.u_error = EFAULT; - return; - } - fp = getf(uap->fdes); - if (fp == 0) - return; - if ((fp->f_flag & FSOCKET) == 0) { - u.u_error = ENOTSOCK; - return; - } - so = fp->f_socket; - u.u_error = connect(so, &in); - if (u.u_error) - return; - s = splnet(); - for (;;) { - /* should use tsleep here */ - if ((*so->so_proto->pr_usrreq)(so, PRU_ISCONN, 0, &in) == 0) - break; - sleep((caddr_t)&so->so_timeo, PZERO+1); - } - splx(s); -} - connect(so, iap) struct socket *so; struct in_addr *iap; { + int s = splnet(); + int error; - return ((*so->so_proto->pr_usrreq)(so, PRU_CONNECT, 0, iap)); + if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) { + error = EISCONN; + goto bad; + } + error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT, 0, (caddr_t)iap); +bad: + splx(s); + return (error); } /* - * Disconnect socket from foreign peer; system call - * interface. Copy in arguments and call internal routine. + * Disconnect from a socket. + * Address parameter is from system call for later multicast + * protocols. Check to make sure that connected and no disconnect + * in progress (for protocol's sake), and then invoke protocol. */ -sdisconnect() -{ - register struct a { - int fdes; - in_addr *addr; - } *uap = (struct a *)u.u_ap; - in_addr in; - register struct file *fp; - - if (uap->addr && - copyin((caddr_t)uap->addr, (caddr_t)&in, sizeof (in))) { - u.u_error = EFAULT; - return; - } - fp = getf(uap->fdes); - if (fp == 0) - return; - if ((fp->f_flag & FSOCKET) == 0) { - u.u_error = ENOTSOCK; - return; - } - disconnect(fp->f_socket, uap->addr ? &in : 0); -} - disconnect(so, iap) struct socket *so; struct in_addr *iap; { + int s = splnet(); + int error; - u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT, 0, iap); -} - -/* - * Send data on socket. - */ -ssend() -{ - register struct a { - int fdes; - in_addr *ain; - caddr_t cbuf; - int count; - } *uap = (struct a *)u.u_ap; - register struct file *fp; - struct in_addr in; - - fp = getf(uap->fdes); - if (fp == 0) - return; - if ((fp->f_flag & FSOCKET) == 0) { - u.u_error = ENOTSOCK; - return; - } - if (uap->count < 0) { - u.u_error = EINVAL; - return; + if ((so->so_state & SS_ISCONNECTED) == 0) { + error = ENOTCONN; + goto bad; } - u.u_base = uap->cbuf; - u.u_count = uap->count; - u.u_segflg = 0; - if (useracc(u.u_base, u.u_count, B_READ) == 0 || - uap->ain && copyin((caddr_t)uap->ain, (caddr_t)&in, sizeof (in))) { - u.u_error = EFAULT; - return; + if (so->so_state & SS_ISDISCONNECTING) { + error = EALREADY; + goto bad; } - u.u_error = send(fp->f_socket, uap->ain ? &in : 0); + error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT, 0, 0); +bad: + splx(s); + return (error); } +/* + * Send on a socket. + * If send must go all at once and message is larger than + * send buffering, then hard error. + * Lock against other senders. + * If must go all at once and not enough room now, then + * inform user that this would block and do nothing. + */ send(so, iap) register struct socket *so; struct in_addr *iap; { - register struct mbuf *m, **mp; - struct mbuf *top; + struct mbuf *top = 0; + register struct mbuf *m, **mp = ⊤ + register int bufs; + register int len; int error = 0; + int s; - if (so->so_proto->pr_flags & PR_ATOMIC) { - if (u.u_count > so->so_snd.sb_hiwat) { - error = EMSGSIZE; + if (so->so_state & SS_CANTSENDMORE) + return (EPIPE); + if (sosendallatonce(so) && u.u_count > so->so_snd.sb_hiwat) + return (EMSGSIZE); + if ((so->so_snd.sb_flags & SB_LOCK) && (so->so_options & SO_NBIO)) + return (EWOULDBLOCK); + sblock(&so->so_snd); +#define snderr(errno) { error = errno; splx(s); goto release; } + + s = splnet(); +again: + if ((so->so_state & SS_ISCONNECTED) == 0) { + if (so->so_proto->pr_flags & PR_CONNREQUIRED) + snderr(ENOTCONN); + if (iap == 0) + snderr(EDESTADDRREQ); + } + if (so->so_error) + snderr(so->so_error); + if (top) { + error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, top, iap); + if (error) { + splx(s); goto release; } + top = 0; + mp = ⊤ } -again: - while (so->so_snd.sb_flags & SB_LOCK) { - so->so_snd.sb_flags |= SB_WANT; - sleep((caddr_t)&so->so_snd.sb_flags, PZERO+1); - } - if (so->so_snd.sb_hiwat - so->so_snd.sb_cc < u.u_count) { - so->so_snd.sb_flags |= SB_WAIT; - sleep((caddr_t)&so->so_snd.sb_cc, PZERO+1); + if (sosendallatonce(so) && sbspace(&so->so_snd) < u.u_count) { + if (so->so_options & SO_NBIO) + snderr(EWOULDBLOCK); + sbunlock(&so->so_snd); + sbwait(&so->so_snd); + splx(s); goto again; } - so->so_snd.sb_flags |= SB_LOCK; - while (u.u_count > 0) { - register int bufs = so->so_snd.sb_mbmax - so->so_snd.sb_mbcnt; - while (bufs == 0) { - so->so_snd.sb_flags |= SB_WAIT; - sleep((caddr_t)&so->so_snd.sb_cc, PZERO+1); + splx(s); + while (u.u_count > 0 && sbspace(&so->so_snd) > 0) { + MGET(m, 1); + if (m == NULL) { + error = ENOBUFS; + m_freem(top); + goto release; } - mp = ⊤ - top = 0; - while (--bufs >= 0 && u.u_count > 0) { - register int len; - MGET(m, 1); - if (m == NULL) { - error = ENOBUFS; - m_freem(top); - goto release; - } - if (u.u_count >= PGSIZE && bufs >= NMBPG) { - register struct mbuf *p; - MPGET(p, 1); - if (p == 0) - goto nopages; - m->m_off = (int)p - (int)m; - len = PGSIZE; - } else { + if (u.u_count >= PGSIZE && bufs >= NMBPG) { + register struct mbuf *p; + MPGET(p, 1); + if (p == 0) + goto nopages; + m->m_off = (int)p - (int)m; + len = PGSIZE; + } else { nopages: - m->m_off = MMINOFF; - len = MIN(MLEN, u.u_count); - } - iomove(mtod(m, caddr_t), len, B_WRITE); - m->m_len = len; - *mp = m; - mp = &m->m_next; + m->m_off = MMINOFF; + len = MIN(MLEN, u.u_count); } - { register int s = splnet(); - error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, top, iap); - splx(s); } - if (error) - break; + iomove(mtod(m, caddr_t), len, B_WRITE); + m->m_len = len; + *mp = m; + mp = &m->m_next; } + s = splnet(); + goto again; + release: - so->so_snd.sb_flags &= ~SB_LOCK; - if (so->so_snd.sb_flags & SB_WANT) - wakeup((caddr_t)&so->so_snd.sb_flags); + sbunlock(&so->so_snd); return (error); } -/* - * Receive data on socket. - */ -sreceive() -{ - register struct a { - int fdes; - in_addr *ain; - caddr_t cbuf; - int count; - } *uap = (struct a *)u.u_ap; - register struct file *fp; - struct in_addr *in; - - fp = getf(uap->fdes); - if (fp == 0) - return; - if ((fp->f_flag & FSOCKET) == 0) { - u.u_error = ENOTSOCK; - return; - } - if (uap->count < 0) { - u.u_error = EINVAL; - return; - } - u.u_base = uap->cbuf; - u.u_count = uap->count; - u.u_segflg = 0; - if (useracc(u.u_base, u.u_count, B_WRITE) == 0 || - uap->ain && copyin((caddr_t)uap->ain, (caddr_t)&in, sizeof (in))) { - u.u_error = EFAULT; - return; - } - receive(fp->f_socket, uap->ain ? &in : 0); -} - receive(so, iap) register struct socket *so; struct in_addr *iap; { register struct mbuf *m, *n; - register int eor, len, s; + register int len; + int eor, s, error = 0; -again: - while (so->so_rcv.sb_flags & SB_LOCK) { - so->so_rcv.sb_flags |= SB_WANT; - sleep((caddr_t)&so->so_rcv.sb_flags, PZERO+1); - } +restart: + sblock(&so->so_rcv); + s = splnet(); + +#define rcverr(errno) { error = errno; splx(s); goto release; } if (so->so_rcv.sb_cc == 0) { - if ((so->so_proto->pr_usrreq)(so, PRU_ISDISCONN, 0, 0) == 0) - return; - so->so_rcv.sb_flags |= SB_WAIT; + if ((so->so_state & SS_ISCONNECTED) == 0 && + (so->so_proto->pr_flags & PR_CONNREQUIRED)) + rcverr(ENOTCONN); + if (so->so_state & SS_CANTRCVMORE) { + splx(s); + goto release; + } + if (so->so_options & SO_NBIO) + rcverr(EWOULDBLOCK); + sbunlock(&so->so_rcv); sleep((caddr_t)&so->so_rcv.sb_cc, PZERO+1); - goto again; + goto restart; } - so->so_rcv.sb_flags |= SB_LOCK; m = so->so_rcv.sb_mb; if (m == 0) panic("receive"); + + /* + * Pull address off receive chain, if protocol + * put one there. + */ + if ((so->so_proto->pr_flags & PR_ADDR)) { + so->so_rcv.sb_mb = m->m_next; + if (iap) { + so->so_rcv.sb_cc -= m->m_len; + len = MIN(m->m_len, sizeof (struct in_addr)); + bcopy(mtod(m, caddr_t), (caddr_t)iap, len); + } else + *iap = zeroin_addr; + m = so->so_rcv.sb_mb; + if (m == 0) + panic("receive 2"); + } + + /* + * Next pull data off the chain. + * Stop at eor or when run out of space in user buffer. + */ eor = 0; do { len = MIN(m->m_len, u.u_count); if (len == m->m_len) { eor = (int)m->m_act; - so->so_rcv.sb_mb = m->m_next; - so->so_rcv.sb_cc -= len; - if (so->so_rcv.sb_cc < 0) - panic("receive 2"); + sbfree(&so->so_rcv, m); } splx(s); iomove(mtod(m, caddr_t), len, B_READ); @@ -447,34 +336,33 @@ again: m->m_off += len; m->m_len -= len; so->so_rcv.sb_cc -= len; - if (so->so_rcv.sb_cc < 0) - panic("receive 3"); } } while ((m = so->so_rcv.sb_mb) && u.u_count && !eor); + + /* + * If atomic protocol discard rest of record. + */ if ((so->so_proto->pr_flags & PR_ATOMIC) && eor == 0) do { - m = so->so_rcv.sb_mb; if (m == 0) - panic("receive 4"); - so->so_rcv.sb_cc -= m->m_len; - if (so->so_rcv.sb_cc < 0) - panic("receive 5"); + panic("receive 3"); + sbfree(&so->so_rcv, m); eor = (int)m->m_act; so->so_rcv.sb_mb = m->m_next; MFREE(m, n); + m = n; } while (eor == 0); - if (iap) - if ((so->so_proto->pr_flags & PR_ADDR)) { - m = so->so_rcv.sb_mb; - if (m == 0) - panic("receive 6"); - so->so_rcv.sb_mb = m->m_next; - so->so_rcv.sb_cc -= m->m_len; - len = MIN(m->m_len, sizeof (struct in_addr)); - bcopy(mtod(m, caddr_t), (caddr_t)iap, len); - } else - *iap = zeroin_addr; - (*so->so_proto->pr_usrreq)(so, PRU_RCVD, m, 0); + + /* + * If protocol cares, inform it that + * there is more space in the receive buffer. + */ + if ((so->so_proto->pr_flags & PR_WANTRCVD) && so->so_pcb) + (*so->so_proto->pr_usrreq)(so, PRU_RCVD, 0, 0); + +release: + sounlock(&so->so_rcv); + splx(s); } skioctl(so, cmd, cmdp) @@ -502,17 +390,5 @@ skioctl(so, cmd, cmdp) } } - -sostat(so) - struct socket *so; -{ - -} - -/* - * Generic protocol handler. - */ -gen_usrreq() -{ - -} +/*###417 [cc] operands of = have incompatible types %%%*/ +/*###417 [cc] zeroin_addr undefined %%%*/ diff --git a/usr/src/sys/kern/uipc_syscalls.c b/usr/src/sys/kern/uipc_syscalls.c index a0ddc1ddf4..8b9cf129a0 100644 --- a/usr/src/sys/kern/uipc_syscalls.c +++ b/usr/src/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* uipc_syscalls.c 4.1 81/11/10 */ +/* uipc_syscalls.c 4.2 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" @@ -23,56 +23,56 @@ * These routines interface the socket routines to UNIX, * isolating the system interface from the socket-protocol interface. * - * DO SPLICE STUFF - * DO PIPE STUFF - * DO PORTALS - * DO ASSOCIATIONS - * DO NEWFD STUFF + * TODO: + * SO_NEWFDONCONN + * SO_INTNOTIFY */ +static struct in_addr localaddr = { PF_LOCAL }; /* - * Socket system call interface. Copy in arguments - * set up file descriptor and call internal socket - * creation routine. + * Pipe system call interface. */ -ssocket() +spipe() { - register struct a { - int type; - struct in_addr *ain; - int options; - } *uap = (struct a *)u.u_ap; - struct in_addr in; - struct socket *so0; - register struct socket *so; - register struct file *fp; - - if ((fp = falloc()) == NULL) - return; - fp->f_flag = FSOCKET|FREAD|FWRITE; - if (copyin((caddr_t)uap->ain, &in, sizeof (in))) { - u.u_error = EFAULT; + register struct file *rf, *wf; + struct socket *rso, *wso; + int r; + struct in_addr waddr; + + u.u_error = socket(&rso, SOCK_STREAM, &localaddr, SO_ACCEPTCONN); + if (u.u_error) return; - } - u.u_error = socket(&so0, uap->type, &in, uap->options); + u.u_error = socket(&wso, SOCK_STREAM, &localaddr, 0); if (u.u_error) - goto bad; - fp->f_socket = so; + goto free; + rf = falloc(); + if (rf == NULL) + goto free2; + r = u.u_r.r_val1; + rf->f_flag = FREAD|FSOCKET; + rf->f_socket = rso; + wf = falloc(); + if (wf == NULL) + goto free3; + wf->f_flag = FWRITE|FSOCKET; + wf->f_socket = wso; + u.u_r.r_val2 = u.u_r.r_val1; + u.u_r.r_val1 = r; + if (pi_connect(rso, wso) == 0) + goto free4; return; -bad: +free4: + wf->f_count = 0; u.u_ofile[u.u_r.r_val1] = 0; - fp->f_count = 0; +free3: + rf->f_count = 0; + u.u_ofile[r] = 0; +free2: + sofree(wso); +free: + sofree(rso); } -/* - * Pipe system call interface. - */ -spipe() -{ - -} - -static struct in_addr portalproto = { PF_PORTAL, /* rest don't care */ }; /* * Portal system call interface. * @@ -81,7 +81,7 @@ static struct in_addr portalproto = { PF_PORTAL, /* rest don't care */ }; * A long sequence of steps is necessary: * 1. a socket must be allocated * 2. the server name length must be determined - * 3. the protal must be entered into the file system + * 3. the portal must be entered into the file system * 4. the portal type and server must be entered into the portals' file * 5. a file descriptor referencing the socket+inode must be returned * If any errors occur in this process we must back it all out. @@ -103,7 +103,7 @@ sportal() /* * Allocate the socket for the portal. */ - u.u_error = socket(&so, SOCK_STREAM, &portalproto, SO_NEWFDONCONN); + u.u_error = socket(&so, SOCK_STREAM, &localaddr, SO_NEWFDONCONN); if (u.u_error) return; @@ -173,15 +173,15 @@ sportal() fp = falloc(); if (fp == NULL) goto bad2; - fp->f_flags = FPORTAL|FSOCKET; + fp->f_flag = FPORTAL|FSOCKET; fp->f_inode = ip; - fp->f_socket = s; + fp->f_socket = so; /* * Make the in-core inode reference the socket. */ - ip->i_socket = s; - prele(ip); + ip->i_un.i_socket = so; + irele(ip); return; bad2: err = u.u_error; @@ -190,78 +190,76 @@ bad2: unlink(); u.u_error = err; bad: - sofree(s); -} - -/* - * Close a socket on last file table reference removal. - * Initiate disconnect if connected. - * Free socket when disconnect complete. - */ -skclose(so) - register struct socket *so; -{ - int s = splnet(); /* conservative */ - - if (so->so_pcb == 0) - goto discard; - if (so->so_state & SS_ISCONNECTED) { - u.u_error = disconnect(so, 0); - if (u.u_error) { - splx(s); - return; - } - if ((so->so_state & SS_ISDISCONNECTING) && - (so->so_options & SO_NBIO)) { - u.u_error = EINPROGRESS; - splx(s); - return; - } - while (so->so_state & SS_ISCONNECTED) - sleep((caddr_t)&so->so_timeo, PZERO+1); - } - u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_DETACH, 0, 0); -discard: sofree(so); - splx(s); } /* - * Select a socket. + * Splice system call interface. */ -soselect(so, flag) - register struct socket *so; - int flag; +ssplice() { - register struct proc *p; + register struct a { + int fd1; + int fd2; + } *ap = (struct a *)u.u_ap; + struct file *f1, *f2; + struct socket *pso, *pso2; - if (soreadable(so)) - return (1); - if ((p = so->so_rcv.sb_sel) && p->p_wchan == (caddr_t)select) - so->so_rcv.sb_flags |= SB_COLL; - else - so->so_rcv.sb_sel = u.u_procp; - return (0); + f1 = getf(ap->fd1); + if (f1 == NULL) + return; + f2 = getf(ap->fd2); + if (f2 == NULL) + return; + if ((f1->f_flag & FSOCKET) == 0 || (f2->f_flag & FSOCKET) == 0) { + u.u_error = ENOTSOCK; + return; + } + if (f1->f_count > 1 || f2->f_count > 1) { + u.u_error = ETOOMANYREFS; + return; + } + u.u_error = pi_splice(f1->f_socket, f2->f_socket); + if (u.u_error) + return; + u.u_ofile[ap->fd1] = 0; + u.u_ofile[ap->fd2] = 0; + f1->f_count = 0; + f2->f_count = 0; } /* - * Wakeup read sleep/select'ers. + * Socket system call interface. Copy in arguments + * set up file descriptor and call internal socket + * creation routine. */ -sowakeup(so) - struct socket *so; +ssocket() { + register struct a { + int type; + struct in_addr *ain; + int options; + } *uap = (struct a *)u.u_ap; + struct in_addr in; + struct socket *so0; + register struct file *fp; - if (so->so_rcv.sb_sel && soreadable(so)) { - selwakeup(so->so_rcv.sb_sel, so->so_rcv.sb_flags & SB_COLL); - so->so_rcv.sb_sel = 0; - so->so_rcv.sb_flags &= ~SB_COLL; - } - if (so->so_rcv.sb_flags & SB_WAIT) { - so->so_rcv.sb_flags &= ~SB_WAIT; - wakeup((caddr_t)&so->so_rcv.sb_cc); + if ((fp = falloc()) == NULL) + return; + fp->f_flag = FSOCKET|FREAD|FWRITE; + if (copyin((caddr_t)uap->ain, &in, sizeof (in))) { + u.u_error = EFAULT; + return; } + u.u_error = socket(&so0, uap->type, &in, uap->options); + if (u.u_error) + goto bad; + fp->f_socket = so0; + return; +bad: + u.u_ofile[u.u_r.r_val1] = 0; + fp->f_count = 0; } - /* * Connect socket to foreign peer; system call * interface. Copy in arguments and call internal routine. @@ -293,13 +291,17 @@ sconnect() if (u.u_error) return; s = splnet(); - if ((so->so_options & SO_NBIO) && (so->so_state & SS_ISCONN) == 0) { + if ((so->so_options & SO_NBIO) && + (so->so_state & SS_ISCONNECTING)) { u.u_error = EINPROGRESS; + splx(s); return; } - while ((so->so_state & (SS_ISCONN|SS_ISCONNING)) == SS_ISCONNING) + 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; + splx(s); } /* @@ -314,6 +316,7 @@ sdisconnect() } *uap = (struct a *)u.u_ap; in_addr in; register struct file *fp; + register struct socket *so; int s; if (uap->addr && @@ -328,15 +331,21 @@ sdisconnect() u.u_error = ENOTSOCK; return; } - u.u_error = disconnect(fp->f_socket, uap->addr ? &in : 0); + so = fp->f_socket; + u.u_error = disconnect(so, uap->addr ? &in : 0); if (u.u_error) return; s = splnet(); - if ((so->so_options&SO_NBIO) && (so->so_state&SS_ISCONNECTED)) - return (EINPROGRESS); - while ((so)->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTING) == SS_ISDISCONNECTING) + if ((so->so_options&SO_NBIO) && (so->so_state&SS_ISDISCONNECTING)) { + u.u_error = EINPROGRESS; + splx(s); + return; + } + while (so->so_state & SS_ISDISCONNECTING) sleep((caddr_t)&so->so_timeo, PZERO+1); u.u_error = so->so_error; + so->so_error = 0; + splx(s); } /* @@ -367,7 +376,7 @@ ssend() u.u_base = uap->cbuf; u.u_count = uap->count; u.u_segflg = 0; - if (useracc(u.u_base, u.u_count, B_READ) == 0 || + if (useracc(uap->cbuf, uap->count, B_READ) == 0 || uap->ain && copyin((caddr_t)uap->ain, (caddr_t)&in, sizeof (in))) { u.u_error = EFAULT; return; @@ -375,3 +384,38 @@ ssend() u.u_error = send(fp->f_socket, uap->ain ? &in : 0); } +/* + * Receive data on socket. + */ +sreceive() +{ + register struct a { + int fdes; + in_addr *ain; + caddr_t cbuf; + int count; + } *uap = (struct a *)u.u_ap; + register struct file *fp; + struct in_addr *in; + + fp = getf(uap->fdes); + if (fp == 0) + return; + if ((fp->f_flag & FSOCKET) == 0) { + u.u_error = ENOTSOCK; + return; + } + if (uap->count < 0) { + u.u_error = EINVAL; + return; + } + u.u_base = uap->cbuf; + u.u_count = uap->count; + u.u_segflg = 0; + if (useracc(uap->cbuf, uap->count, B_WRITE) == 0 || + uap->ain && copyin((caddr_t)uap->ain, (caddr_t)&in, sizeof (in))) { + u.u_error = EFAULT; + return; + } + receive(fp->f_socket, uap->ain ? &in : 0); +} diff --git a/usr/src/sys/kern/vfs_syscalls.c b/usr/src/sys/kern/vfs_syscalls.c index fd52d55b6a..700575cb44 100644 --- a/usr/src/sys/kern/vfs_syscalls.c +++ b/usr/src/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* vfs_syscalls.c 4.12 81/11/08 */ +/* vfs_syscalls.c 4.13 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" @@ -31,7 +31,7 @@ fstat() if (fp == NULL) return; if (fp->f_flag & FSOCKET) - sostat(fp->f_socket); + u.u_error = sostat(fp->f_socket, uap->sb); else stat1(fp->f_inode, uap->sb); } diff --git a/usr/src/sys/kern/vfs_vnops.c b/usr/src/sys/kern/vfs_vnops.c index 872892660c..5e88155d4d 100644 --- a/usr/src/sys/kern/vfs_vnops.c +++ b/usr/src/sys/kern/vfs_vnops.c @@ -1,4 +1,4 @@ -/* vfs_vnops.c 4.14 81/11/08 */ +/* vfs_vnops.c 4.15 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" @@ -58,7 +58,7 @@ closef(fp) } flag = fp->f_flag; if (flag & FSOCKET) { - skclose(fp->f_socket); + soclose(fp->f_socket); fp->f_socket = 0; fp->f_count = 0; return; diff --git a/usr/src/sys/ufs/ffs/ffs_vnops.c b/usr/src/sys/ufs/ffs/ffs_vnops.c index 51de032610..4d32ffbd00 100644 --- a/usr/src/sys/ufs/ffs/ffs_vnops.c +++ b/usr/src/sys/ufs/ffs/ffs_vnops.c @@ -1,4 +1,4 @@ -/* ffs_vnops.c 4.12 81/11/08 */ +/* ffs_vnops.c 4.13 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" @@ -31,7 +31,7 @@ fstat() if (fp == NULL) return; if (fp->f_flag & FSOCKET) - sostat(fp->f_socket); + u.u_error = sostat(fp->f_socket, uap->sb); else stat1(fp->f_inode, uap->sb); } diff --git a/usr/src/sys/ufs/ffs/ufs_vnops.c b/usr/src/sys/ufs/ffs/ufs_vnops.c index 55b39177c2..4f4e5d4d31 100644 --- a/usr/src/sys/ufs/ffs/ufs_vnops.c +++ b/usr/src/sys/ufs/ffs/ufs_vnops.c @@ -1,4 +1,4 @@ -/* ufs_vnops.c 4.12 81/11/08 */ +/* ufs_vnops.c 4.13 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" @@ -31,7 +31,7 @@ fstat() if (fp == NULL) return; if (fp->f_flag & FSOCKET) - sostat(fp->f_socket); + u.u_error = sostat(fp->f_socket, uap->sb); else stat1(fp->f_inode, uap->sb); } diff --git a/usr/src/sys/ufs/lfs/lfs_vnops.c b/usr/src/sys/ufs/lfs/lfs_vnops.c index 32ae34e358..03ab6bc76c 100644 --- a/usr/src/sys/ufs/lfs/lfs_vnops.c +++ b/usr/src/sys/ufs/lfs/lfs_vnops.c @@ -1,4 +1,4 @@ -/* lfs_vnops.c 4.12 81/11/08 */ +/* lfs_vnops.c 4.13 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" @@ -31,7 +31,7 @@ fstat() if (fp == NULL) return; if (fp->f_flag & FSOCKET) - sostat(fp->f_socket); + u.u_error = sostat(fp->f_socket, uap->sb); else stat1(fp->f_inode, uap->sb); } diff --git a/usr/src/sys/ufs/ufs/ufs_vnops.c b/usr/src/sys/ufs/ufs/ufs_vnops.c index 55b39177c2..4f4e5d4d31 100644 --- a/usr/src/sys/ufs/ufs/ufs_vnops.c +++ b/usr/src/sys/ufs/ufs/ufs_vnops.c @@ -1,4 +1,4 @@ -/* ufs_vnops.c 4.12 81/11/08 */ +/* ufs_vnops.c 4.13 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" @@ -31,7 +31,7 @@ fstat() if (fp == NULL) return; if (fp->f_flag & FSOCKET) - sostat(fp->f_socket); + u.u_error = sostat(fp->f_socket, uap->sb); else stat1(fp->f_inode, uap->sb); } diff --git a/usr/src/sys/vax/vax/machdep.c b/usr/src/sys/vax/vax/machdep.c index d170087f46..99eb6b2603 100644 --- a/usr/src/sys/vax/vax/machdep.c +++ b/usr/src/sys/vax/vax/machdep.c @@ -1,12 +1,7 @@ -/* machdep.c 4.44 81/11/08 */ +/* machdep.c 4.45 81/11/14 */ #include "../h/param.h" #include "../h/systm.h" -#ifdef INET -#include "../net/inet.h" -#include "../net/inet_systm.h" -#include "../net/inet_host.h" -#endif INET #include "../h/dir.h" #include "../h/user.h" #include "../h/map.h" @@ -121,9 +116,6 @@ startup(firstaddr) valloc(argmap, struct map, ARGMAPSIZE); valloc(kernelmap, struct map, nproc); valloc(mbmap, struct map, nmbpages/2); -#ifdef INET - valloclim(host, struct host, nhost, hostNHOST); -#endif INET /* * Now allocate space for core map */ -- 2.20.1