xref: /original-bsd/sys/kern/sys_socket.c (revision 7323bcb8)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  *	@(#)sys_socket.c	7.3 (Berkeley) 06/29/88
18  */
19 
20 #include "param.h"
21 #include "systm.h"
22 #include "dir.h"
23 #include "user.h"
24 #include "file.h"
25 #include "mbuf.h"
26 #include "protosw.h"
27 #include "socket.h"
28 #include "socketvar.h"
29 #include "ioctl.h"
30 #include "uio.h"
31 #include "stat.h"
32 
33 #include "../net/if.h"
34 #include "../net/route.h"
35 
36 int	soo_rw(), soo_ioctl(), soo_select(), soo_close();
37 struct	fileops socketops =
38     { soo_rw, soo_ioctl, soo_select, soo_close };
39 
40 soo_rw(fp, rw, uio)
41 	struct file *fp;
42 	enum uio_rw rw;
43 	struct uio *uio;
44 {
45 	int soreceive(), sosend();
46 
47 	return (
48 	    (*(rw==UIO_READ?soreceive:sosend))
49 	      ((struct socket *)fp->f_data, 0, uio, 0, 0));
50 }
51 
52 soo_ioctl(fp, cmd, data)
53 	struct file *fp;
54 	int cmd;
55 	register caddr_t data;
56 {
57 	register struct socket *so = (struct socket *)fp->f_data;
58 
59 	switch (cmd) {
60 
61 	case FIONBIO:
62 		if (*(int *)data)
63 			so->so_state |= SS_NBIO;
64 		else
65 			so->so_state &= ~SS_NBIO;
66 		return (0);
67 
68 	case FIOASYNC:
69 		if (*(int *)data)
70 			so->so_state |= SS_ASYNC;
71 		else
72 			so->so_state &= ~SS_ASYNC;
73 		return (0);
74 
75 	case FIONREAD:
76 		*(int *)data = so->so_rcv.sb_cc;
77 		return (0);
78 
79 	case SIOCSPGRP:
80 		so->so_pgrp = *(int *)data;
81 		return (0);
82 
83 	case SIOCGPGRP:
84 		*(int *)data = so->so_pgrp;
85 		return (0);
86 
87 	case SIOCATMARK:
88 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
89 		return (0);
90 	}
91 	/*
92 	 * Interface/routing/protocol specific ioctls:
93 	 * interface and routing ioctls should have a
94 	 * different entry since a socket's unnecessary
95 	 */
96 #define	cmdbyte(x)	(((x) >> 8) & 0xff)
97 	if (cmdbyte(cmd) == 'i')
98 		return (ifioctl(so, cmd, data));
99 	if (cmdbyte(cmd) == 'r')
100 		return (rtioctl(cmd, data));
101 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
102 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
103 }
104 
105 soo_select(fp, which)
106 	struct file *fp;
107 	int which;
108 {
109 	register struct socket *so = (struct socket *)fp->f_data;
110 	register int s = splnet();
111 
112 	switch (which) {
113 
114 	case FREAD:
115 		if (soreadable(so)) {
116 			splx(s);
117 			return (1);
118 		}
119 		sbselqueue(&so->so_rcv);
120 		break;
121 
122 	case FWRITE:
123 		if (sowriteable(so)) {
124 			splx(s);
125 			return (1);
126 		}
127 		sbselqueue(&so->so_snd);
128 		break;
129 
130 	case 0:
131 		if (so->so_oobmark ||
132 		    (so->so_state & SS_RCVATMARK)) {
133 			splx(s);
134 			return (1);
135 		}
136 		sbselqueue(&so->so_rcv);
137 		break;
138 	}
139 	splx(s);
140 	return (0);
141 }
142 
143 /*ARGSUSED*/
144 soo_stat(so, ub)
145 	register struct socket *so;
146 	register struct stat *ub;
147 {
148 
149 	bzero((caddr_t)ub, sizeof (*ub));
150 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
151 	    (struct mbuf *)ub, (struct mbuf *)0,
152 	    (struct mbuf *)0));
153 }
154 
155 soo_close(fp)
156 	struct file *fp;
157 {
158 	int error = 0;
159 
160 	if (fp->f_data)
161 		error = soclose((struct socket *)fp->f_data);
162 	fp->f_data = 0;
163 	return (error);
164 }
165