xref: /original-bsd/sys/kern/sys_socket.c (revision 72b8f354)
1 /*
2  * Copyright (c) 1982, 1986, 1990 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)sys_socket.c	7.8 (Berkeley) 06/28/90
8  */
9 
10 #include "param.h"
11 #include "systm.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_read(), soo_write(), soo_ioctl(), soo_select(), soo_close();
26 struct	fileops socketops =
27     { soo_read, soo_write, soo_ioctl, soo_select, soo_close };
28 
29 /* ARGSUSED */
30 soo_read(fp, uio, cred)
31 	struct file *fp;
32 	struct uio *uio;
33 	struct ucred *cred;
34 {
35 
36 	return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0,
37 		uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0));
38 }
39 
40 /* ARGSUSED */
41 soo_write(fp, uio, cred)
42 	struct file *fp;
43 	struct uio *uio;
44 	struct ucred *cred;
45 {
46 
47 	return (sosend((struct socket *)fp->f_data, (struct mbuf *)0,
48 		uio, (struct mbuf *)0, (struct mbuf *)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 			so->so_rcv.sb_flags |= SB_ASYNC;
71 			so->so_snd.sb_flags |= SB_ASYNC;
72 		} else {
73 			so->so_state &= ~SS_ASYNC;
74 			so->so_rcv.sb_flags &= ~SB_ASYNC;
75 			so->so_snd.sb_flags &= ~SB_ASYNC;
76 		}
77 		return (0);
78 
79 	case FIONREAD:
80 		*(int *)data = so->so_rcv.sb_cc;
81 		return (0);
82 
83 	case SIOCSPGRP:
84 		so->so_pgid = *(int *)data;
85 		return (0);
86 
87 	case SIOCGPGRP:
88 		*(int *)data = so->so_pgid;
89 		return (0);
90 
91 	case SIOCATMARK:
92 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
93 		return (0);
94 	}
95 	/*
96 	 * Interface/routing/protocol specific ioctls:
97 	 * interface and routing ioctls should have a
98 	 * different entry since a socket's unnecessary
99 	 */
100 	if (IOCGROUP(cmd) == 'i')
101 		return (ifioctl(so, cmd, data));
102 	if (IOCGROUP(cmd) == 'r')
103 		return (rtioctl(cmd, data));
104 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
105 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
106 }
107 
108 soo_select(fp, which)
109 	struct file *fp;
110 	int which;
111 {
112 	register struct socket *so = (struct socket *)fp->f_data;
113 	register int s = splnet();
114 
115 	switch (which) {
116 
117 	case FREAD:
118 		if (soreadable(so)) {
119 			splx(s);
120 			return (1);
121 		}
122 		sbselqueue(&so->so_rcv);
123 		break;
124 
125 	case FWRITE:
126 		if (sowriteable(so)) {
127 			splx(s);
128 			return (1);
129 		}
130 		sbselqueue(&so->so_snd);
131 		break;
132 
133 	case 0:
134 		if (so->so_oobmark ||
135 		    (so->so_state & SS_RCVATMARK)) {
136 			splx(s);
137 			return (1);
138 		}
139 		sbselqueue(&so->so_rcv);
140 		break;
141 	}
142 	splx(s);
143 	return (0);
144 }
145 
146 /*ARGSUSED*/
147 soo_stat(so, ub)
148 	register struct socket *so;
149 	register struct stat *ub;
150 {
151 
152 	bzero((caddr_t)ub, sizeof (*ub));
153 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
154 	    (struct mbuf *)ub, (struct mbuf *)0,
155 	    (struct mbuf *)0));
156 }
157 
158 soo_close(fp)
159 	struct file *fp;
160 {
161 	int error = 0;
162 
163 	if (fp->f_data)
164 		error = soclose((struct socket *)fp->f_data);
165 	fp->f_data = 0;
166 	return (error);
167 }
168