xref: /csrg-svn/sys/kern/sys_socket.c (revision 68317)
123386Smckusick /*
263178Sbostic  * Copyright (c) 1982, 1986, 1990, 1993
363178Sbostic  *	The Regents of the University of California.  All rights reserved.
423386Smckusick  *
544445Sbostic  * %sccs.include.redist.c%
633921Sbostic  *
7*68317Scgd  *	@(#)sys_socket.c	8.3 (Berkeley) 02/14/95
823386Smckusick  */
912794Ssam 
1056517Sbostic #include <sys/param.h>
1156517Sbostic #include <sys/systm.h>
1256517Sbostic #include <sys/proc.h>
1356517Sbostic #include <sys/file.h>
1456517Sbostic #include <sys/mbuf.h>
1556517Sbostic #include <sys/protosw.h>
1656517Sbostic #include <sys/socket.h>
1756517Sbostic #include <sys/socketvar.h>
1856517Sbostic #include <sys/ioctl.h>
1956517Sbostic #include <sys/stat.h>
2012794Ssam 
2156517Sbostic #include <net/if.h>
2256517Sbostic #include <net/route.h>
2312794Ssam 
2412794Ssam struct	fileops socketops =
2537728Smckusick     { soo_read, soo_write, soo_ioctl, soo_select, soo_close };
2612794Ssam 
2737728Smckusick /* ARGSUSED */
28*68317Scgd int
soo_read(fp,uio,cred)2937728Smckusick soo_read(fp, uio, cred)
3012794Ssam 	struct file *fp;
3112794Ssam 	struct uio *uio;
3237728Smckusick 	struct ucred *cred;
3312794Ssam {
3412794Ssam 
3537728Smckusick 	return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0,
3640935Skarels 		uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0));
3712794Ssam }
3812794Ssam 
3937728Smckusick /* ARGSUSED */
40*68317Scgd int
soo_write(fp,uio,cred)4137728Smckusick soo_write(fp, uio, cred)
4237728Smckusick 	struct file *fp;
4337728Smckusick 	struct uio *uio;
4437728Smckusick 	struct ucred *cred;
4537728Smckusick {
4637728Smckusick 
4737728Smckusick 	return (sosend((struct socket *)fp->f_data, (struct mbuf *)0,
4840935Skarels 		uio, (struct mbuf *)0, (struct mbuf *)0, 0));
4937728Smckusick }
5037728Smckusick 
51*68317Scgd int
soo_ioctl(fp,cmd,data,p)5247540Skarels soo_ioctl(fp, cmd, data, p)
5312794Ssam 	struct file *fp;
5468171Scgd 	u_long cmd;
5512794Ssam 	register caddr_t data;
5647540Skarels 	struct proc *p;
5712794Ssam {
5812794Ssam 	register struct socket *so = (struct socket *)fp->f_data;
5912794Ssam 
6012794Ssam 	switch (cmd) {
6112794Ssam 
6212794Ssam 	case FIONBIO:
6312794Ssam 		if (*(int *)data)
6412794Ssam 			so->so_state |= SS_NBIO;
6512794Ssam 		else
6612794Ssam 			so->so_state &= ~SS_NBIO;
6713050Ssam 		return (0);
6812794Ssam 
6912794Ssam 	case FIOASYNC:
7043897Skarels 		if (*(int *)data) {
7112794Ssam 			so->so_state |= SS_ASYNC;
7243897Skarels 			so->so_rcv.sb_flags |= SB_ASYNC;
7343897Skarels 			so->so_snd.sb_flags |= SB_ASYNC;
7443897Skarels 		} else {
7512794Ssam 			so->so_state &= ~SS_ASYNC;
7643897Skarels 			so->so_rcv.sb_flags &= ~SB_ASYNC;
7743897Skarels 			so->so_snd.sb_flags &= ~SB_ASYNC;
7843897Skarels 		}
7913050Ssam 		return (0);
8012794Ssam 
8113001Ssam 	case FIONREAD:
8213001Ssam 		*(int *)data = so->so_rcv.sb_cc;
8313050Ssam 		return (0);
8413001Ssam 
8512794Ssam 	case SIOCSPGRP:
8637478Ssklower 		so->so_pgid = *(int *)data;
8713050Ssam 		return (0);
8812794Ssam 
8912794Ssam 	case SIOCGPGRP:
9037478Ssklower 		*(int *)data = so->so_pgid;
9113050Ssam 		return (0);
9212794Ssam 
9312794Ssam 	case SIOCATMARK:
9412794Ssam 		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
9513050Ssam 		return (0);
9612794Ssam 	}
9713050Ssam 	/*
9813050Ssam 	 * Interface/routing/protocol specific ioctls:
9913050Ssam 	 * interface and routing ioctls should have a
10013050Ssam 	 * different entry since a socket's unnecessary
10113050Ssam 	 */
10240935Skarels 	if (IOCGROUP(cmd) == 'i')
10347540Skarels 		return (ifioctl(so, cmd, data, p));
10440935Skarels 	if (IOCGROUP(cmd) == 'r')
10547540Skarels 		return (rtioctl(cmd, data, p));
10613050Ssam 	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
10713050Ssam 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
10812794Ssam }
10912794Ssam 
110*68317Scgd int
soo_select(fp,which,p)11147540Skarels soo_select(fp, which, p)
11212794Ssam 	struct file *fp;
11312794Ssam 	int which;
11447540Skarels 	struct proc *p;
11512794Ssam {
11612794Ssam 	register struct socket *so = (struct socket *)fp->f_data;
11712794Ssam 	register int s = splnet();
11812794Ssam 
11912794Ssam 	switch (which) {
12012794Ssam 
12112794Ssam 	case FREAD:
12212794Ssam 		if (soreadable(so)) {
12312794Ssam 			splx(s);
12412794Ssam 			return (1);
12512794Ssam 		}
12652524Smckusick 		selrecord(p, &so->so_rcv.sb_sel);
12752524Smckusick 		so->so_rcv.sb_flags |= SB_SEL;
12812794Ssam 		break;
12912794Ssam 
13012794Ssam 	case FWRITE:
13112794Ssam 		if (sowriteable(so)) {
13212794Ssam 			splx(s);
13312794Ssam 			return (1);
13412794Ssam 		}
13552524Smckusick 		selrecord(p, &so->so_snd.sb_sel);
13652524Smckusick 		so->so_snd.sb_flags |= SB_SEL;
13712794Ssam 		break;
13824768Skarels 
13924768Skarels 	case 0:
14052524Smckusick 		if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) {
14124768Skarels 			splx(s);
14224768Skarels 			return (1);
14324768Skarels 		}
14452524Smckusick 		selrecord(p, &so->so_rcv.sb_sel);
14552524Smckusick 		so->so_rcv.sb_flags |= SB_SEL;
14624768Skarels 		break;
14712794Ssam 	}
14812794Ssam 	splx(s);
14912794Ssam 	return (0);
15012794Ssam }
15112794Ssam 
152*68317Scgd int
soo_stat(so,ub)15313045Ssam soo_stat(so, ub)
15413045Ssam 	register struct socket *so;
15512794Ssam 	register struct stat *ub;
15612794Ssam {
15712794Ssam 
15812794Ssam 	bzero((caddr_t)ub, sizeof (*ub));
15950429Skarels 	ub->st_mode = S_IFSOCK;
16012794Ssam 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
16112794Ssam 	    (struct mbuf *)ub, (struct mbuf *)0,
16212794Ssam 	    (struct mbuf *)0));
16312794Ssam }
16412794Ssam 
16548028Smckusick /* ARGSUSED */
166*68317Scgd int
soo_close(fp,p)16748028Smckusick soo_close(fp, p)
16812794Ssam 	struct file *fp;
16948028Smckusick 	struct proc *p;
17012794Ssam {
17114032Ssam 	int error = 0;
17233921Sbostic 
17314032Ssam 	if (fp->f_data)
17414032Ssam 		error = soclose((struct socket *)fp->f_data);
17512794Ssam 	fp->f_data = 0;
17612794Ssam 	return (error);
17712794Ssam }
178