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