xref: /original-bsd/sys/kern/sys_socket.c (revision 2852c678)
1 /*
2  * Copyright (c) 1982, 1986, 1990 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)sys_socket.c	7.11 (Berkeley) 04/16/91
8  */
9 
10 #include "param.h"
11 #include "systm.h"
12 #include "file.h"
13 #include "mbuf.h"
14 #include "protosw.h"
15 #include "socket.h"
16 #include "socketvar.h"
17 #include "ioctl.h"
18 #include "stat.h"
19 
20 #include "net/if.h"
21 #include "net/route.h"
22 
23 struct	fileops socketops =
24     { soo_read, soo_write, soo_ioctl, soo_select, soo_close };
25 
26 /* ARGSUSED */
27 soo_read(fp, uio, cred)
28 	struct file *fp;
29 	struct uio *uio;
30 	struct ucred *cred;
31 {
32 
33 	return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0,
34 		uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0));
35 }
36 
37 /* ARGSUSED */
38 soo_write(fp, uio, cred)
39 	struct file *fp;
40 	struct uio *uio;
41 	struct ucred *cred;
42 {
43 
44 	return (sosend((struct socket *)fp->f_data, (struct mbuf *)0,
45 		uio, (struct mbuf *)0, (struct mbuf *)0, 0));
46 }
47 
48 soo_ioctl(fp, cmd, data, p)
49 	struct file *fp;
50 	int cmd;
51 	register caddr_t data;
52 	struct proc *p;
53 {
54 	register struct socket *so = (struct socket *)fp->f_data;
55 
56 	switch (cmd) {
57 
58 	case FIONBIO:
59 		if (*(int *)data)
60 			so->so_state |= SS_NBIO;
61 		else
62 			so->so_state &= ~SS_NBIO;
63 		return (0);
64 
65 	case FIOASYNC:
66 		if (*(int *)data) {
67 			so->so_state |= SS_ASYNC;
68 			so->so_rcv.sb_flags |= SB_ASYNC;
69 			so->so_snd.sb_flags |= SB_ASYNC;
70 		} else {
71 			so->so_state &= ~SS_ASYNC;
72 			so->so_rcv.sb_flags &= ~SB_ASYNC;
73 			so->so_snd.sb_flags &= ~SB_ASYNC;
74 		}
75 		return (0);
76 
77 	case FIONREAD:
78 		*(int *)data = so->so_rcv.sb_cc;
79 		return (0);
80 
81 	case SIOCSPGRP:
82 		so->so_pgid = *(int *)data;
83 		return (0);
84 
85 	case SIOCGPGRP:
86 		*(int *)data = so->so_pgid;
87 		return (0);
88 
89 	case SIOCATMARK:
90 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
91 		return (0);
92 	}
93 	/*
94 	 * Interface/routing/protocol specific ioctls:
95 	 * interface and routing ioctls should have a
96 	 * different entry since a socket's unnecessary
97 	 */
98 	if (IOCGROUP(cmd) == 'i')
99 		return (ifioctl(so, cmd, data, p));
100 	if (IOCGROUP(cmd) == 'r')
101 		return (rtioctl(cmd, data, p));
102 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
103 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
104 }
105 
106 soo_select(fp, which, p)
107 	struct file *fp;
108 	int which;
109 	struct proc *p;
110 {
111 	register struct socket *so = (struct socket *)fp->f_data;
112 	register int s = splnet();
113 
114 	switch (which) {
115 
116 	case FREAD:
117 		if (soreadable(so)) {
118 			splx(s);
119 			return (1);
120 		}
121 		sbselqueue(&so->so_rcv, p);
122 		break;
123 
124 	case FWRITE:
125 		if (sowriteable(so)) {
126 			splx(s);
127 			return (1);
128 		}
129 		sbselqueue(&so->so_snd, p);
130 		break;
131 
132 	case 0:
133 		if (so->so_oobmark ||
134 		    (so->so_state & SS_RCVATMARK)) {
135 			splx(s);
136 			return (1);
137 		}
138 		sbselqueue(&so->so_rcv, p);
139 		break;
140 	}
141 	splx(s);
142 	return (0);
143 }
144 
145 soo_stat(so, ub)
146 	register struct socket *so;
147 	register struct stat *ub;
148 {
149 
150 	bzero((caddr_t)ub, sizeof (*ub));
151 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
152 	    (struct mbuf *)ub, (struct mbuf *)0,
153 	    (struct mbuf *)0));
154 }
155 
156 /* ARGSUSED */
157 soo_close(fp, p)
158 	struct file *fp;
159 	struct proc *p;
160 {
161 	int error = 0;
162 
163 	if (fp->f_data)
164 		error = soclose((struct socket *)fp->f_data);
165 	fp->f_data = 0;
166 	return (error);
167 }
168