xref: /csrg-svn/sys/kern/sys_socket.c (revision 29106)
123386Smckusick /*
2*29106Smckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
323386Smckusick  * All rights reserved.  The Berkeley software License Agreement
423386Smckusick  * specifies the terms and conditions for redistribution.
523386Smckusick  *
6*29106Smckusick  *	@(#)sys_socket.c	7.1 (Berkeley) 06/05/86
723386Smckusick  */
812794Ssam 
917095Sbloom #include "param.h"
1017095Sbloom #include "systm.h"
1117095Sbloom #include "dir.h"
1217095Sbloom #include "user.h"
1317095Sbloom #include "file.h"
1417095Sbloom #include "mbuf.h"
1517095Sbloom #include "protosw.h"
1617095Sbloom #include "socket.h"
1717095Sbloom #include "socketvar.h"
1817095Sbloom #include "ioctl.h"
1917095Sbloom #include "uio.h"
2017095Sbloom #include "stat.h"
2112794Ssam 
2212794Ssam #include "../net/if.h"
2312794Ssam #include "../net/route.h"
2412794Ssam 
2513045Ssam int	soo_rw(), soo_ioctl(), soo_select(), soo_close();
2612794Ssam struct	fileops socketops =
2713045Ssam     { soo_rw, soo_ioctl, soo_select, soo_close };
2812794Ssam 
2912794Ssam soo_rw(fp, rw, uio)
3012794Ssam 	struct file *fp;
3112794Ssam 	enum uio_rw rw;
3212794Ssam 	struct uio *uio;
3312794Ssam {
3412794Ssam 	int soreceive(), sosend();
3512794Ssam 
3612794Ssam 	return (
3712794Ssam 	    (*(rw==UIO_READ?soreceive:sosend))
3812794Ssam 	      ((struct socket *)fp->f_data, 0, uio, 0, 0));
3912794Ssam }
4012794Ssam 
4112794Ssam soo_ioctl(fp, cmd, data)
4212794Ssam 	struct file *fp;
4312794Ssam 	int cmd;
4412794Ssam 	register caddr_t data;
4512794Ssam {
4612794Ssam 	register struct socket *so = (struct socket *)fp->f_data;
4712794Ssam 
4812794Ssam 	switch (cmd) {
4912794Ssam 
5012794Ssam 	case FIONBIO:
5112794Ssam 		if (*(int *)data)
5212794Ssam 			so->so_state |= SS_NBIO;
5312794Ssam 		else
5412794Ssam 			so->so_state &= ~SS_NBIO;
5513050Ssam 		return (0);
5612794Ssam 
5712794Ssam 	case FIOASYNC:
5812794Ssam 		if (*(int *)data)
5912794Ssam 			so->so_state |= SS_ASYNC;
6012794Ssam 		else
6112794Ssam 			so->so_state &= ~SS_ASYNC;
6213050Ssam 		return (0);
6312794Ssam 
6413001Ssam 	case FIONREAD:
6513001Ssam 		*(int *)data = so->so_rcv.sb_cc;
6613050Ssam 		return (0);
6713001Ssam 
6812794Ssam 	case SIOCSPGRP:
6912794Ssam 		so->so_pgrp = *(int *)data;
7013050Ssam 		return (0);
7112794Ssam 
7212794Ssam 	case SIOCGPGRP:
7312794Ssam 		*(int *)data = so->so_pgrp;
7413050Ssam 		return (0);
7512794Ssam 
7612794Ssam 	case SIOCATMARK:
7712794Ssam 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
7813050Ssam 		return (0);
7912794Ssam 	}
8013050Ssam 	/*
8113050Ssam 	 * Interface/routing/protocol specific ioctls:
8213050Ssam 	 * interface and routing ioctls should have a
8313050Ssam 	 * different entry since a socket's unnecessary
8413050Ssam 	 */
8513050Ssam #define	cmdbyte(x)	(((x) >> 8) & 0xff)
8613050Ssam 	if (cmdbyte(cmd) == 'i')
8718366Skarels 		return (ifioctl(so, cmd, data));
8813050Ssam 	if (cmdbyte(cmd) == 'r')
8913050Ssam 		return (rtioctl(cmd, data));
9013050Ssam 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
9113050Ssam 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
9212794Ssam }
9312794Ssam 
9412794Ssam soo_select(fp, which)
9512794Ssam 	struct file *fp;
9612794Ssam 	int which;
9712794Ssam {
9812794Ssam 	register struct socket *so = (struct socket *)fp->f_data;
9912794Ssam 	register int s = splnet();
10012794Ssam 
10112794Ssam 	switch (which) {
10212794Ssam 
10312794Ssam 	case FREAD:
10412794Ssam 		if (soreadable(so)) {
10512794Ssam 			splx(s);
10612794Ssam 			return (1);
10712794Ssam 		}
10812794Ssam 		sbselqueue(&so->so_rcv);
10912794Ssam 		break;
11012794Ssam 
11112794Ssam 	case FWRITE:
11212794Ssam 		if (sowriteable(so)) {
11312794Ssam 			splx(s);
11412794Ssam 			return (1);
11512794Ssam 		}
11612794Ssam 		sbselqueue(&so->so_snd);
11712794Ssam 		break;
11824768Skarels 
11924768Skarels 	case 0:
12024768Skarels 		if (so->so_oobmark ||
12124768Skarels 		    (so->so_state & SS_RCVATMARK)) {
12224768Skarels 			splx(s);
12324768Skarels 			return (1);
12424768Skarels 		}
12524768Skarels 		sbselqueue(&so->so_rcv);
12624768Skarels 		break;
12712794Ssam 	}
12812794Ssam 	splx(s);
12912794Ssam 	return (0);
13012794Ssam }
13112794Ssam 
13213099Ssam /*ARGSUSED*/
13313045Ssam soo_stat(so, ub)
13413045Ssam 	register struct socket *so;
13512794Ssam 	register struct stat *ub;
13612794Ssam {
13712794Ssam 
13812794Ssam 	bzero((caddr_t)ub, sizeof (*ub));
13912794Ssam 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
14012794Ssam 	    (struct mbuf *)ub, (struct mbuf *)0,
14112794Ssam 	    (struct mbuf *)0));
14212794Ssam }
14312794Ssam 
14412794Ssam soo_close(fp)
14512794Ssam 	struct file *fp;
14612794Ssam {
14714032Ssam 	int error = 0;
14814032Ssam 
14914032Ssam 	if (fp->f_data)
15014032Ssam 		error = soclose((struct socket *)fp->f_data);
15112794Ssam 	fp->f_data = 0;
15212794Ssam 	return (error);
15312794Ssam }
154