xref: /original-bsd/sys/kern/sys_socket.c (revision fa348642)
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.9 (Berkeley) 03/17/91
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, p)
52 	struct file *fp;
53 	int cmd;
54 	register caddr_t data;
55 	struct proc *p;
56 {
57 	register struct socket *so = (struct socket *)fp->f_data;
58 
59 	switch (cmd) {
60 
61 	case FIONBIO:
62 		if (*(int *)data)
63 			so->so_state |= SS_NBIO;
64 		else
65 			so->so_state &= ~SS_NBIO;
66 		return (0);
67 
68 	case FIOASYNC:
69 		if (*(int *)data) {
70 			so->so_state |= SS_ASYNC;
71 			so->so_rcv.sb_flags |= SB_ASYNC;
72 			so->so_snd.sb_flags |= SB_ASYNC;
73 		} else {
74 			so->so_state &= ~SS_ASYNC;
75 			so->so_rcv.sb_flags &= ~SB_ASYNC;
76 			so->so_snd.sb_flags &= ~SB_ASYNC;
77 		}
78 		return (0);
79 
80 	case FIONREAD:
81 		*(int *)data = so->so_rcv.sb_cc;
82 		return (0);
83 
84 	case SIOCSPGRP:
85 		so->so_pgid = *(int *)data;
86 		return (0);
87 
88 	case SIOCGPGRP:
89 		*(int *)data = so->so_pgid;
90 		return (0);
91 
92 	case SIOCATMARK:
93 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
94 		return (0);
95 	}
96 	/*
97 	 * Interface/routing/protocol specific ioctls:
98 	 * interface and routing ioctls should have a
99 	 * different entry since a socket's unnecessary
100 	 */
101 	if (IOCGROUP(cmd) == 'i')
102 		return (ifioctl(so, cmd, data, p));
103 	if (IOCGROUP(cmd) == 'r')
104 		return (rtioctl(cmd, data, p));
105 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
106 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
107 }
108 
109 soo_select(fp, which, p)
110 	struct file *fp;
111 	int which;
112 	struct proc *p;
113 {
114 	register struct socket *so = (struct socket *)fp->f_data;
115 	register int s = splnet();
116 
117 	switch (which) {
118 
119 	case FREAD:
120 		if (soreadable(so)) {
121 			splx(s);
122 			return (1);
123 		}
124 		sbselqueue(&so->so_rcv, p);
125 		break;
126 
127 	case FWRITE:
128 		if (sowriteable(so)) {
129 			splx(s);
130 			return (1);
131 		}
132 		sbselqueue(&so->so_snd, p);
133 		break;
134 
135 	case 0:
136 		if (so->so_oobmark ||
137 		    (so->so_state & SS_RCVATMARK)) {
138 			splx(s);
139 			return (1);
140 		}
141 		sbselqueue(&so->so_rcv, p);
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 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
155 	    (struct mbuf *)ub, (struct mbuf *)0,
156 	    (struct mbuf *)0));
157 }
158 
159 soo_close(fp)
160 	struct file *fp;
161 {
162 	int error = 0;
163 
164 	if (fp->f_data)
165 		error = soclose((struct socket *)fp->f_data);
166 	fp->f_data = 0;
167 	return (error);
168 }
169