xref: /csrg-svn/sys/kern/sys_socket.c (revision 37478)
1 /*
2  * Copyright (c) 1982, 1986, 1988 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.4 (Berkeley) 04/22/89
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 ((*(rw == UIO_READ ? soreceive : sosend))
48 	      ((struct socket *)fp->f_data, 0, uio, 0, 0, 0));
49 }
50 
51 soo_ioctl(fp, cmd, data)
52 	struct file *fp;
53 	int cmd;
54 	register caddr_t data;
55 {
56 	register struct socket *so = (struct socket *)fp->f_data;
57 
58 	switch (cmd) {
59 
60 	case FIONBIO:
61 		if (*(int *)data)
62 			so->so_state |= SS_NBIO;
63 		else
64 			so->so_state &= ~SS_NBIO;
65 		return (0);
66 
67 	case FIOASYNC:
68 		if (*(int *)data)
69 			so->so_state |= SS_ASYNC;
70 		else
71 			so->so_state &= ~SS_ASYNC;
72 		return (0);
73 
74 	case FIONREAD:
75 		*(int *)data = so->so_rcv.sb_cc;
76 		return (0);
77 
78 	case SIOCSPGRP:
79 		so->so_pgid = *(int *)data;
80 		return (0);
81 
82 	case SIOCGPGRP:
83 		*(int *)data = so->so_pgid;
84 		return (0);
85 
86 	case SIOCATMARK:
87 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
88 		return (0);
89 	}
90 	/*
91 	 * Interface/routing/protocol specific ioctls:
92 	 * interface and routing ioctls should have a
93 	 * different entry since a socket's unnecessary
94 	 */
95 #define	cmdbyte(x)	(((x) >> 8) & 0xff)
96 	if (cmdbyte(cmd) == 'i')
97 		return (ifioctl(so, cmd, data));
98 	if (cmdbyte(cmd) == 'r')
99 		return (rtioctl(cmd, data));
100 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
101 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
102 }
103 
104 soo_select(fp, which)
105 	struct file *fp;
106 	int which;
107 {
108 	register struct socket *so = (struct socket *)fp->f_data;
109 	register int s = splnet();
110 
111 	switch (which) {
112 
113 	case FREAD:
114 		if (soreadable(so)) {
115 			splx(s);
116 			return (1);
117 		}
118 		sbselqueue(&so->so_rcv);
119 		break;
120 
121 	case FWRITE:
122 		if (sowriteable(so)) {
123 			splx(s);
124 			return (1);
125 		}
126 		sbselqueue(&so->so_snd);
127 		break;
128 
129 	case 0:
130 		if (so->so_oobmark ||
131 		    (so->so_state & SS_RCVATMARK)) {
132 			splx(s);
133 			return (1);
134 		}
135 		sbselqueue(&so->so_rcv);
136 		break;
137 	}
138 	splx(s);
139 	return (0);
140 }
141 
142 /*ARGSUSED*/
143 soo_stat(so, ub)
144 	register struct socket *so;
145 	register struct stat *ub;
146 {
147 
148 	bzero((caddr_t)ub, sizeof (*ub));
149 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
150 	    (struct mbuf *)ub, (struct mbuf *)0,
151 	    (struct mbuf *)0));
152 }
153 
154 soo_close(fp)
155 	struct file *fp;
156 {
157 	int error = 0;
158 
159 	if (fp->f_data)
160 		error = soclose((struct socket *)fp->f_data);
161 	fp->f_data = 0;
162 	return (error);
163 }
164