xref: /original-bsd/sys/kern/sys_socket.c (revision fac0c393)
1 /*
2  * Copyright (c) 1982, 1986, 1990, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)sys_socket.c	8.3 (Berkeley) 02/14/95
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/proc.h>
13 #include <sys/file.h>
14 #include <sys/mbuf.h>
15 #include <sys/protosw.h>
16 #include <sys/socket.h>
17 #include <sys/socketvar.h>
18 #include <sys/ioctl.h>
19 #include <sys/stat.h>
20 
21 #include <net/if.h>
22 #include <net/route.h>
23 
24 struct	fileops socketops =
25     { soo_read, soo_write, soo_ioctl, soo_select, soo_close };
26 
27 /* ARGSUSED */
28 int
29 soo_read(fp, uio, cred)
30 	struct file *fp;
31 	struct uio *uio;
32 	struct ucred *cred;
33 {
34 
35 	return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0,
36 		uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0));
37 }
38 
39 /* ARGSUSED */
40 int
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 int
52 soo_ioctl(fp, cmd, data, p)
53 	struct file *fp;
54 	u_long cmd;
55 	register caddr_t data;
56 	struct proc *p;
57 {
58 	register struct socket *so = (struct socket *)fp->f_data;
59 
60 	switch (cmd) {
61 
62 	case FIONBIO:
63 		if (*(int *)data)
64 			so->so_state |= SS_NBIO;
65 		else
66 			so->so_state &= ~SS_NBIO;
67 		return (0);
68 
69 	case FIOASYNC:
70 		if (*(int *)data) {
71 			so->so_state |= SS_ASYNC;
72 			so->so_rcv.sb_flags |= SB_ASYNC;
73 			so->so_snd.sb_flags |= SB_ASYNC;
74 		} else {
75 			so->so_state &= ~SS_ASYNC;
76 			so->so_rcv.sb_flags &= ~SB_ASYNC;
77 			so->so_snd.sb_flags &= ~SB_ASYNC;
78 		}
79 		return (0);
80 
81 	case FIONREAD:
82 		*(int *)data = so->so_rcv.sb_cc;
83 		return (0);
84 
85 	case SIOCSPGRP:
86 		so->so_pgid = *(int *)data;
87 		return (0);
88 
89 	case SIOCGPGRP:
90 		*(int *)data = so->so_pgid;
91 		return (0);
92 
93 	case SIOCATMARK:
94 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
95 		return (0);
96 	}
97 	/*
98 	 * Interface/routing/protocol specific ioctls:
99 	 * interface and routing ioctls should have a
100 	 * different entry since a socket's unnecessary
101 	 */
102 	if (IOCGROUP(cmd) == 'i')
103 		return (ifioctl(so, cmd, data, p));
104 	if (IOCGROUP(cmd) == 'r')
105 		return (rtioctl(cmd, data, p));
106 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
107 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
108 }
109 
110 int
111 soo_select(fp, which, p)
112 	struct file *fp;
113 	int which;
114 	struct proc *p;
115 {
116 	register struct socket *so = (struct socket *)fp->f_data;
117 	register int s = splnet();
118 
119 	switch (which) {
120 
121 	case FREAD:
122 		if (soreadable(so)) {
123 			splx(s);
124 			return (1);
125 		}
126 		selrecord(p, &so->so_rcv.sb_sel);
127 		so->so_rcv.sb_flags |= SB_SEL;
128 		break;
129 
130 	case FWRITE:
131 		if (sowriteable(so)) {
132 			splx(s);
133 			return (1);
134 		}
135 		selrecord(p, &so->so_snd.sb_sel);
136 		so->so_snd.sb_flags |= SB_SEL;
137 		break;
138 
139 	case 0:
140 		if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) {
141 			splx(s);
142 			return (1);
143 		}
144 		selrecord(p, &so->so_rcv.sb_sel);
145 		so->so_rcv.sb_flags |= SB_SEL;
146 		break;
147 	}
148 	splx(s);
149 	return (0);
150 }
151 
152 int
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 	ub->st_mode = S_IFSOCK;
160 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
161 	    (struct mbuf *)ub, (struct mbuf *)0,
162 	    (struct mbuf *)0));
163 }
164 
165 /* ARGSUSED */
166 int
167 soo_close(fp, p)
168 	struct file *fp;
169 	struct proc *p;
170 {
171 	int error = 0;
172 
173 	if (fp->f_data)
174 		error = soclose((struct socket *)fp->f_data);
175 	fp->f_data = 0;
176 	return (error);
177 }
178