xref: /csrg-svn/sys/kern/sys_socket.c (revision 17095)
1*17095Sbloom /*	sys_socket.c	6.3	84/08/29	*/
212794Ssam 
3*17095Sbloom #include "param.h"
4*17095Sbloom #include "systm.h"
5*17095Sbloom #include "dir.h"
6*17095Sbloom #include "user.h"
7*17095Sbloom #include "file.h"
8*17095Sbloom #include "mbuf.h"
9*17095Sbloom #include "protosw.h"
10*17095Sbloom #include "socket.h"
11*17095Sbloom #include "socketvar.h"
12*17095Sbloom #include "ioctl.h"
13*17095Sbloom #include "uio.h"
14*17095Sbloom #include "stat.h"
1512794Ssam 
1612794Ssam #include "../net/if.h"
1712794Ssam #include "../net/route.h"
1812794Ssam 
1913045Ssam int	soo_rw(), soo_ioctl(), soo_select(), soo_close();
2012794Ssam struct	fileops socketops =
2113045Ssam     { soo_rw, soo_ioctl, soo_select, soo_close };
2212794Ssam 
2312794Ssam soo_rw(fp, rw, uio)
2412794Ssam 	struct file *fp;
2512794Ssam 	enum uio_rw rw;
2612794Ssam 	struct uio *uio;
2712794Ssam {
2812794Ssam 	int soreceive(), sosend();
2912794Ssam 
3012794Ssam 	return (
3112794Ssam 	    (*(rw==UIO_READ?soreceive:sosend))
3212794Ssam 	      ((struct socket *)fp->f_data, 0, uio, 0, 0));
3312794Ssam }
3412794Ssam 
3512794Ssam soo_ioctl(fp, cmd, data)
3612794Ssam 	struct file *fp;
3712794Ssam 	int cmd;
3812794Ssam 	register caddr_t data;
3912794Ssam {
4012794Ssam 	register struct socket *so = (struct socket *)fp->f_data;
4112794Ssam 
4212794Ssam 	switch (cmd) {
4312794Ssam 
4412794Ssam 	case FIONBIO:
4512794Ssam 		if (*(int *)data)
4612794Ssam 			so->so_state |= SS_NBIO;
4712794Ssam 		else
4812794Ssam 			so->so_state &= ~SS_NBIO;
4913050Ssam 		return (0);
5012794Ssam 
5112794Ssam 	case FIOASYNC:
5212794Ssam 		if (*(int *)data)
5312794Ssam 			so->so_state |= SS_ASYNC;
5412794Ssam 		else
5512794Ssam 			so->so_state &= ~SS_ASYNC;
5613050Ssam 		return (0);
5712794Ssam 
5813001Ssam 	case FIONREAD:
5913001Ssam 		*(int *)data = so->so_rcv.sb_cc;
6013050Ssam 		return (0);
6113001Ssam 
6212794Ssam 	case SIOCSPGRP:
6312794Ssam 		so->so_pgrp = *(int *)data;
6413050Ssam 		return (0);
6512794Ssam 
6612794Ssam 	case SIOCGPGRP:
6712794Ssam 		*(int *)data = so->so_pgrp;
6813050Ssam 		return (0);
6912794Ssam 
7012794Ssam 	case SIOCATMARK:
7112794Ssam 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
7213050Ssam 		return (0);
7312794Ssam 	}
7413050Ssam 	/*
7513050Ssam 	 * Interface/routing/protocol specific ioctls:
7613050Ssam 	 * interface and routing ioctls should have a
7713050Ssam 	 * different entry since a socket's unnecessary
7813050Ssam 	 */
7913050Ssam #define	cmdbyte(x)	(((x) >> 8) & 0xff)
8013050Ssam 	if (cmdbyte(cmd) == 'i')
8113050Ssam 		return (ifioctl(cmd, data));
8213050Ssam 	if (cmdbyte(cmd) == 'r')
8313050Ssam 		return (rtioctl(cmd, data));
8413050Ssam 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
8513050Ssam 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
8612794Ssam }
8712794Ssam 
8812794Ssam soo_select(fp, which)
8912794Ssam 	struct file *fp;
9012794Ssam 	int which;
9112794Ssam {
9212794Ssam 	register struct socket *so = (struct socket *)fp->f_data;
9312794Ssam 	register int s = splnet();
9412794Ssam 
9512794Ssam 	switch (which) {
9612794Ssam 
9712794Ssam 	case FREAD:
9812794Ssam 		if (soreadable(so)) {
9912794Ssam 			splx(s);
10012794Ssam 			return (1);
10112794Ssam 		}
10212794Ssam 		sbselqueue(&so->so_rcv);
10312794Ssam 		break;
10412794Ssam 
10512794Ssam 	case FWRITE:
10612794Ssam 		if (sowriteable(so)) {
10712794Ssam 			splx(s);
10812794Ssam 			return (1);
10912794Ssam 		}
11012794Ssam 		sbselqueue(&so->so_snd);
11112794Ssam 		break;
11212794Ssam 	}
11312794Ssam 	splx(s);
11412794Ssam 	return (0);
11512794Ssam }
11612794Ssam 
11713099Ssam /*ARGSUSED*/
11813045Ssam soo_stat(so, ub)
11913045Ssam 	register struct socket *so;
12012794Ssam 	register struct stat *ub;
12112794Ssam {
12212794Ssam 
12312794Ssam 	bzero((caddr_t)ub, sizeof (*ub));
12412794Ssam 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
12512794Ssam 	    (struct mbuf *)ub, (struct mbuf *)0,
12612794Ssam 	    (struct mbuf *)0));
12712794Ssam }
12812794Ssam 
12912794Ssam soo_close(fp)
13012794Ssam 	struct file *fp;
13112794Ssam {
13214032Ssam 	int error = 0;
13314032Ssam 
13414032Ssam 	if (fp->f_data)
13514032Ssam 		error = soclose((struct socket *)fp->f_data);
13612794Ssam 	fp->f_data = 0;
13712794Ssam 	return (error);
13812794Ssam }
139