xref: /original-bsd/sys/kern/sys_socket.c (revision 94e7bb75)
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.13 (Berkeley) 02/15/92
8  */
9 
10 #include "param.h"
11 #include "systm.h"
12 #include "proc.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 "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 soo_read(fp, uio, cred)
29 	struct file *fp;
30 	struct uio *uio;
31 	struct ucred *cred;
32 {
33 
34 	return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0,
35 		uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0));
36 }
37 
38 /* ARGSUSED */
39 soo_write(fp, uio, cred)
40 	struct file *fp;
41 	struct uio *uio;
42 	struct ucred *cred;
43 {
44 
45 	return (sosend((struct socket *)fp->f_data, (struct mbuf *)0,
46 		uio, (struct mbuf *)0, (struct mbuf *)0, 0));
47 }
48 
49 soo_ioctl(fp, cmd, data, p)
50 	struct file *fp;
51 	int cmd;
52 	register caddr_t data;
53 	struct proc *p;
54 {
55 	register struct socket *so = (struct socket *)fp->f_data;
56 
57 	switch (cmd) {
58 
59 	case FIONBIO:
60 		if (*(int *)data)
61 			so->so_state |= SS_NBIO;
62 		else
63 			so->so_state &= ~SS_NBIO;
64 		return (0);
65 
66 	case FIOASYNC:
67 		if (*(int *)data) {
68 			so->so_state |= SS_ASYNC;
69 			so->so_rcv.sb_flags |= SB_ASYNC;
70 			so->so_snd.sb_flags |= SB_ASYNC;
71 		} else {
72 			so->so_state &= ~SS_ASYNC;
73 			so->so_rcv.sb_flags &= ~SB_ASYNC;
74 			so->so_snd.sb_flags &= ~SB_ASYNC;
75 		}
76 		return (0);
77 
78 	case FIONREAD:
79 		*(int *)data = so->so_rcv.sb_cc;
80 		return (0);
81 
82 	case SIOCSPGRP:
83 		so->so_pgid = *(int *)data;
84 		return (0);
85 
86 	case SIOCGPGRP:
87 		*(int *)data = so->so_pgid;
88 		return (0);
89 
90 	case SIOCATMARK:
91 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
92 		return (0);
93 	}
94 	/*
95 	 * Interface/routing/protocol specific ioctls:
96 	 * interface and routing ioctls should have a
97 	 * different entry since a socket's unnecessary
98 	 */
99 	if (IOCGROUP(cmd) == 'i')
100 		return (ifioctl(so, cmd, data, p));
101 	if (IOCGROUP(cmd) == 'r')
102 		return (rtioctl(cmd, data, p));
103 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
104 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
105 }
106 
107 soo_select(fp, which, p)
108 	struct file *fp;
109 	int which;
110 	struct proc *p;
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 		selrecord(p, &so->so_rcv.sb_sel);
123 		so->so_rcv.sb_flags |= SB_SEL;
124 		break;
125 
126 	case FWRITE:
127 		if (sowriteable(so)) {
128 			splx(s);
129 			return (1);
130 		}
131 		selrecord(p, &so->so_snd.sb_sel);
132 		so->so_snd.sb_flags |= SB_SEL;
133 		break;
134 
135 	case 0:
136 		if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) {
137 			splx(s);
138 			return (1);
139 		}
140 		selrecord(p, &so->so_rcv.sb_sel);
141 		so->so_rcv.sb_flags |= SB_SEL;
142 		break;
143 	}
144 	splx(s);
145 	return (0);
146 }
147 
148 soo_stat(so, ub)
149 	register struct socket *so;
150 	register struct stat *ub;
151 {
152 
153 	bzero((caddr_t)ub, sizeof (*ub));
154 	ub->st_mode = S_IFSOCK;
155 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
156 	    (struct mbuf *)ub, (struct mbuf *)0,
157 	    (struct mbuf *)0));
158 }
159 
160 /* ARGSUSED */
161 soo_close(fp, p)
162 	struct file *fp;
163 	struct proc *p;
164 {
165 	int error = 0;
166 
167 	if (fp->f_data)
168 		error = soclose((struct socket *)fp->f_data);
169 	fp->f_data = 0;
170 	return (error);
171 }
172