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
soo_read(fp,uio,cred)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
soo_write(fp,uio,cred)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
soo_ioctl(fp,cmd,data,p)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
soo_select(fp,which,p)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
soo_stat(so,ub)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
soo_close(fp,p)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