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