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