xref: /csrg-svn/sys/kern/sys_generic.c (revision 8118)
1*8118Sroot /*	sys_generic.c	5.14	82/09/08	*/
27423Sroot 
37423Sroot #include "../h/param.h"
47423Sroot #include "../h/systm.h"
57423Sroot #include "../h/dir.h"
67423Sroot #include "../h/user.h"
77423Sroot #include "../h/tty.h"
87423Sroot #include "../h/file.h"
97423Sroot #include "../h/inode.h"
107423Sroot #include "../h/buf.h"
117423Sroot #include "../h/proc.h"
127423Sroot #include "../h/inline.h"
137423Sroot #include "../h/conf.h"
147423Sroot #include "../h/socket.h"
157423Sroot #include "../h/socketvar.h"
167423Sroot #include "../h/fs.h"
177487Skre #ifdef MUSH
187487Skre #include "../h/quota.h"
197487Skre #include "../h/share.h"
207487Skre #else
217487Skre #define	CHARGE(nothing)
227487Skre #endif
237500Sroot #include "../h/descrip.h"
247714Sroot #include "../h/uio.h"
257423Sroot 
267423Sroot /*
277423Sroot  * Read system call.
287423Sroot  */
297423Sroot read()
307423Sroot {
317423Sroot 	register struct a {
327423Sroot 		int	fdes;
337423Sroot 		char	*cbuf;
347423Sroot 		unsigned count;
357820Sroot 	} *uap = (struct a *)u.u_ap;
367746Sroot 	struct uio auio;
377746Sroot 	struct iovec aiov;
387423Sroot 
397820Sroot 	aiov.iov_base = (caddr_t)uap->cbuf;
407820Sroot 	aiov.iov_len = uap->count;
417820Sroot 	auio.uio_iov = &aiov;
427820Sroot 	auio.uio_iovcnt = 1;
437820Sroot 	rwuio(&auio, UIO_READ);
447820Sroot }
457820Sroot 
467820Sroot readv()
477820Sroot {
487820Sroot 	register struct a {
497820Sroot 		int	fdes;
507820Sroot 		struct	iovec *iovp;
517820Sroot 		int	iovcnt;
527820Sroot 	} *uap = (struct a *)u.u_ap;
537820Sroot 	struct uio auio;
547820Sroot 	struct iovec aiov[16];		/* XXX */
557820Sroot 
567820Sroot 	if (uap->iovcnt <= 0 || uap->iovcnt > sizeof(aiov)/sizeof(aiov[0])) {
577423Sroot 		u.u_error = EINVAL;
587423Sroot 		return;
597423Sroot 	}
607820Sroot 	auio.uio_iov = aiov;
617820Sroot 	auio.uio_iovcnt = uap->iovcnt;
627820Sroot 	if (copyin((caddr_t)uap->iovp, (caddr_t)aiov,
637820Sroot 	    (unsigned)(uap->iovcnt * sizeof (struct iovec)))) {
647820Sroot 		u.u_error = EFAULT;
657423Sroot 		return;
667423Sroot 	}
677820Sroot 	rwuio(&auio, UIO_READ);
687423Sroot }
697423Sroot 
707423Sroot /*
717423Sroot  * Write system call
727423Sroot  */
737423Sroot write()
747423Sroot {
757423Sroot 	register struct a {
767423Sroot 		int	fdes;
777423Sroot 		char	*cbuf;
787820Sroot 		int	count;
797820Sroot 	} *uap = (struct a *)u.u_ap;
807820Sroot 	struct uio auio;
817820Sroot 	struct iovec aiov;
827423Sroot 
837820Sroot 	auio.uio_iov = &aiov;
847820Sroot 	auio.uio_iovcnt = 1;
857820Sroot 	aiov.iov_base = uap->cbuf;
867820Sroot 	aiov.iov_len = uap->count;
877820Sroot 	rwuio(&auio, UIO_WRITE);
887820Sroot }
897820Sroot 
907820Sroot writev()
917820Sroot {
927820Sroot 	register struct a {
937820Sroot 		int	fdes;
947820Sroot 		struct	iovec *iovp;
957820Sroot 		int	iovcnt;
967820Sroot 	} *uap = (struct a *)u.u_ap;
977820Sroot 	struct uio auio;
987820Sroot 	struct iovec aiov[16];		/* XXX */
997820Sroot 
1007820Sroot 	if (uap->iovcnt <= 0 || uap->iovcnt > sizeof(aiov)/sizeof(aiov[0])) {
1017423Sroot 		u.u_error = EINVAL;
1027423Sroot 		return;
1037423Sroot 	}
1047820Sroot 	auio.uio_iov = aiov;
1057820Sroot 	auio.uio_iovcnt = uap->iovcnt;
1067820Sroot 	if (copyin((caddr_t)uap->iovp, (caddr_t)aiov,
1077820Sroot 	    (unsigned)(uap->iovcnt * sizeof (struct iovec)))) {
1087820Sroot 		u.u_error = EFAULT;
1097820Sroot 		return;
1107820Sroot 	}
1117820Sroot 	rwuio(&auio, UIO_WRITE);
1127820Sroot }
1137820Sroot 
1147820Sroot rwuio(uio, rw)
1157820Sroot 	register struct uio *uio;
1167820Sroot 	enum uio_rw rw;
1177820Sroot {
1187820Sroot 	struct a {
1197820Sroot 		int	fdes;
1207820Sroot 	};
1217820Sroot 	register struct file *fp;
1227820Sroot 	register struct iovec *iov;
1237820Sroot 	register struct inode *ip;
1247820Sroot 	int i, count;
1257820Sroot 
1267820Sroot 	GETF(fp, ((struct a *)u.u_ap)->fdes);
1277820Sroot 	if ((fp->f_flag&(rw==UIO_READ ? FREAD : FWRITE)) == 0) {
1287423Sroot 		u.u_error = EBADF;
1297423Sroot 		return;
1307423Sroot 	}
1317820Sroot 	uio->uio_resid = 0;
1327820Sroot 	uio->uio_segflg = 0;
1337820Sroot 	iov = uio->uio_iov;
1347820Sroot 	for (i = 0; i < uio->uio_iovcnt; i++) {
1357820Sroot 		if (iov->iov_len < 0) {
1367820Sroot 			u.u_error = EINVAL;
1377820Sroot 			return;
1387820Sroot 		}
1397820Sroot 		uio->uio_resid += iov->iov_len;
1407820Sroot 		if (uio->uio_resid < 0) {
1417820Sroot 			u.u_error = EINVAL;
1427820Sroot 			return;
1437820Sroot 		}
1447820Sroot 	}
1457820Sroot 	count = uio->uio_resid;
146*8118Sroot 	if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) {
1477820Sroot 		if (uio->uio_resid == count)
1487423Sroot 			u.u_eosys = RESTARTSYS;
1497820Sroot 	} else if (fp->f_type == DTYPE_SOCKET) {
1507820Sroot 		int sosend(), soreceive();
1517820Sroot 		u.u_error =
1527820Sroot 		    (*(rw==UIO_READ?soreceive:sosend))
1537820Sroot 		      (fp->f_socket, (struct sockaddr *)0, uio);
1547820Sroot 	} else {
1557423Sroot 		ip = fp->f_inode;
1567820Sroot 		uio->uio_offset = fp->f_offset;
1577423Sroot 		if ((ip->i_mode&IFMT) == IFREG) {
1587423Sroot 			ilock(ip);
1597820Sroot 			u.u_error = rwip(ip, uio, rw);
1607423Sroot 			iunlock(ip);
1617423Sroot 		} else
1627820Sroot 			u.u_error = rwip(ip, uio, rw);
1637820Sroot 		fp->f_offset += count - uio->uio_resid;
1647423Sroot 	}
1657820Sroot 	u.u_r.r_val1 = count - uio->uio_resid;
1667423Sroot }
1677423Sroot 
1687820Sroot rdwri(rw, ip, base, len, offset, segflg, aresid)
1697820Sroot 	struct inode *ip;
1707820Sroot 	caddr_t base;
1717820Sroot 	int len, offset, segflg;
1727820Sroot 	int *aresid;
1737820Sroot 	enum uio_rw rw;
1747500Sroot {
1757820Sroot 	struct uio auio;
1767820Sroot 	struct iovec aiov;
1777820Sroot 	int error;
1787423Sroot 
1797820Sroot 	auio.uio_iov = &aiov;
1807820Sroot 	auio.uio_iovcnt = 1;
1817820Sroot 	aiov.iov_base = base;
1827820Sroot 	aiov.iov_len = len;
1837820Sroot 	auio.uio_resid = len;
1847820Sroot 	auio.uio_offset = offset;
1857820Sroot 	auio.uio_segflg = segflg;
1867820Sroot 	error = rwip(ip, &auio, rw);
1877820Sroot 	if (aresid)
1887820Sroot 		*aresid = auio.uio_resid;
1897820Sroot 	else
1907820Sroot 		if (auio.uio_resid)
1917820Sroot 			error = EIO;
1927820Sroot 	return (error);
1937500Sroot }
1947500Sroot 
1957820Sroot rwip(ip, uio, rw)
1967820Sroot 	register struct inode *ip;
1977820Sroot 	register struct uio *uio;
1987820Sroot 	enum uio_rw rw;
1997500Sroot {
2007820Sroot 	dev_t dev = (dev_t)ip->i_rdev;
2017820Sroot 	struct buf *bp;
2027820Sroot 	struct fs *fs;
2037820Sroot 	daddr_t lbn, bn;
2047820Sroot 	register int on, type;
2057820Sroot 	register unsigned n;
2067820Sroot 	int size;
2077820Sroot 	long bsize;
2087820Sroot 	extern int mem_no;
2097820Sroot 	int error = 0;
2107500Sroot 
2117820Sroot 	if (rw != UIO_READ && rw != UIO_WRITE)
2127820Sroot 		panic("rwip");
2137820Sroot 	if (uio->uio_offset < 0 &&
2147820Sroot 	    ((ip->i_mode&IFMT) != IFCHR || mem_no != major(dev)))
2157820Sroot 		return (EINVAL); if (rw == UIO_READ)
2167820Sroot 		ip->i_flag |= IACC;
2177820Sroot 	type = ip->i_mode&IFMT;
2187820Sroot 	if (type == IFCHR) {
2197820Sroot #ifdef QUOTA
2207820Sroot 		register c = uio->uio_resid;
2217820Sroot #endif
2227820Sroot 		if (rw == UIO_READ)
2237820Sroot 			(*cdevsw[major(dev)].d_read)(dev, uio);
2247820Sroot 		else {
2257820Sroot 			ip->i_flag |= IUPD|ICHG;
2267820Sroot 			(*cdevsw[major(dev)].d_write)(dev, uio);
2277820Sroot 		}
2287820Sroot 		CHARGE(sc_tio * (c - uio->uio_resid));
2297820Sroot 		return (u.u_error);
2307820Sroot 	}
2317820Sroot 	if (rw == UIO_WRITE && type == IFREG &&
2328036Sroot 	    uio->uio_offset + uio->uio_resid >
2338036Sroot 	      u.u_rlimit[RLIMIT_FSIZE].rlim_cur) {
2347820Sroot 		psignal(u.u_procp, SIGXFSZ);
2357820Sroot 		return (EMFILE);
2367820Sroot 	}
2377820Sroot 	if (type != IFBLK) {
2387820Sroot 		dev = ip->i_dev;
2397820Sroot 		fs = ip->i_fs;
2407820Sroot 		bsize = fs->fs_bsize;
2417820Sroot 	} else
2427820Sroot 		bsize = BLKDEV_IOSIZE;
2437820Sroot 	do {
2447820Sroot 		lbn = uio->uio_offset / bsize;
2457820Sroot 		on = uio->uio_offset % bsize;
2467820Sroot 		n = MIN((unsigned)(bsize - on), uio->uio_resid);
2477820Sroot 		if (type != IFBLK) {
2487820Sroot 			if (rw == UIO_READ) {
2497820Sroot 				int diff = ip->i_size - uio->uio_offset;
2507820Sroot 				if (diff <= 0)
2517820Sroot 					return (0);
2527820Sroot 				if (diff < n)
2537820Sroot 					n = diff;
2547820Sroot 			}
2557820Sroot 			bn = fsbtodb(fs,
2567820Sroot 			    bmap(ip, lbn, rw == UIO_WRITE ? B_WRITE: B_READ, (int)(on+n)));
2577820Sroot 			if (u.u_error || rw == UIO_WRITE && (long)bn<0)
2587820Sroot 				return (u.u_error);
2597820Sroot 			if (rw == UIO_WRITE && uio->uio_offset + n > ip->i_size &&
2607820Sroot 			   (type == IFDIR || type == IFREG || type == IFLNK))
2617820Sroot 				ip->i_size = uio->uio_offset + n;
2627820Sroot 			size = blksize(fs, ip, lbn);
2637820Sroot 		} else {
2647820Sroot 			bn = lbn * (BLKDEV_IOSIZE/DEV_BSIZE);
2657820Sroot 			rablock = bn + (BLKDEV_IOSIZE/DEV_BSIZE);
2667820Sroot 			rasize = size = bsize;
2677820Sroot 		}
2687820Sroot 		if (rw == UIO_READ) {
2697820Sroot 			if ((long)bn<0) {
2707820Sroot 				bp = geteblk(size);
2717820Sroot 				clrbuf(bp);
2727820Sroot 			} else if (ip->i_lastr + 1 == lbn)
2737820Sroot 				bp = breada(dev, bn, size, rablock, rasize);
2747820Sroot 			else
2757820Sroot 				bp = bread(dev, bn, size);
2767820Sroot 			ip->i_lastr = lbn;
2777820Sroot 		} else {
2787820Sroot 			int i, count;
2797820Sroot 
2807820Sroot 			count = howmany(size, DEV_BSIZE);
2817820Sroot 			for (i = 0; i < count; i += CLSIZE)
2827820Sroot 				if (mfind(dev, bn + i))
2837820Sroot 					munhash(dev, bn + i);
2847820Sroot 			if (n == bsize)
2857820Sroot 				bp = getblk(dev, bn, size);
2867820Sroot 			else
2877820Sroot 				bp = bread(dev, bn, size);
2887820Sroot 		}
2897820Sroot 		n = MIN(n, size - bp->b_resid);
2907820Sroot 		if (bp->b_flags & B_ERROR) {
2917820Sroot 			error = EIO;
2927820Sroot 			brelse(bp);
2937820Sroot 			goto bad;
2947820Sroot 		}
2957820Sroot 		u.u_error =
2967820Sroot 		    uiomove(bp->b_un.b_addr+on, (u_int)n, rw, uio);
2977820Sroot 		if (rw == UIO_READ) {
2987820Sroot 			if (n + on == bsize || uio->uio_offset == ip->i_size)
2997820Sroot 				bp->b_flags |= B_AGE;
3007820Sroot 			brelse(bp);
3017820Sroot 		} else {
3027820Sroot 			if ((ip->i_mode&IFMT) == IFDIR)
3037820Sroot 				bwrite(bp);
3047820Sroot 			else if (n + on == bsize) {
3057820Sroot 				bp->b_flags |= B_AGE;
3067820Sroot 				bawrite(bp);
3077820Sroot 			} else
3087820Sroot 				bdwrite(bp);
3097820Sroot 			ip->i_flag |= IUPD|ICHG;
3107820Sroot 			if (u.u_ruid != 0)
3117820Sroot 				ip->i_mode &= ~(ISUID|ISGID);
3127820Sroot 		}
3137820Sroot 	} while (u.u_error == 0 && uio->uio_resid > 0 && n != 0);
3147820Sroot bad:
3157820Sroot 	return (error);
3167500Sroot }
3177500Sroot 
3187820Sroot uiomove(cp, n, rw, uio)
3197820Sroot 	register caddr_t cp;
3207820Sroot 	register int n;
3217820Sroot 	enum uio_rw rw;
3227820Sroot 	register struct uio *uio;
3237820Sroot {
3247820Sroot 	register struct iovec *iov;
3257820Sroot 	int error;
3267820Sroot 	u_int cnt;
3277820Sroot 
3287820Sroot 	while (n > 0 && uio->uio_resid) {
3297820Sroot 		iov = uio->uio_iov;
3307820Sroot 		cnt = iov->iov_len;
3317820Sroot 		if (cnt == 0) {
3327820Sroot 			uio->uio_iov++;
3337820Sroot 			uio->uio_iovcnt--;
3347820Sroot 			continue;
3357820Sroot 		}
3367820Sroot 		if (cnt > n)
3377820Sroot 			cnt = n;
3387820Sroot 		switch (uio->uio_segflg) {
3397820Sroot 
3407820Sroot 		case 0:
3417820Sroot 		case 2:
3427820Sroot 			if (rw == UIO_READ)
3437820Sroot 				error = copyout(cp, iov->iov_base, cnt);
3447820Sroot 			else
3457820Sroot 				error = copyin(iov->iov_base, cp, cnt);
3467820Sroot 			if (error)
3477820Sroot 				return (error);
3487820Sroot 			break;
3497820Sroot 
3507820Sroot 		case 1:
3517820Sroot 			if (rw == UIO_READ)
3527820Sroot 				bcopy((caddr_t)cp, iov->iov_base, cnt);
3537820Sroot 			else
3547820Sroot 				bcopy(iov->iov_base, (caddr_t)cp, cnt);
3557820Sroot 			break;
3567820Sroot 		}
3577820Sroot 		iov->iov_base += cnt;
3587820Sroot 		iov->iov_len -= cnt;
3597820Sroot 		uio->uio_resid -= cnt;
3607820Sroot 		uio->uio_offset += cnt;
3617820Sroot 		cp += cnt;
3627820Sroot 		n -= cnt;
3637820Sroot 	}
3647820Sroot 	return (error);
3657820Sroot }
3667820Sroot 
3677423Sroot /*
3687820Sroot  * Give next character to user as result of read.
3697820Sroot  */
3707820Sroot ureadc(c, uio)
3717820Sroot 	register int c;
3727820Sroot 	register struct uio *uio;
3737820Sroot {
3747820Sroot 	register struct iovec *iov;
3757820Sroot 
3767820Sroot again:
3777820Sroot 	if (uio->uio_iovcnt == 0)
3787820Sroot 		panic("ureadc");
3797820Sroot 	iov = uio->uio_iov;
3807820Sroot 	if (iov->iov_len <= 0 || uio->uio_resid <= 0) {
3817820Sroot 		uio->uio_iovcnt--;
3827820Sroot 		uio->uio_iov++;
3837820Sroot 		goto again;
3847820Sroot 	}
3857820Sroot 	switch (uio->uio_segflg) {
3867820Sroot 
3877820Sroot 	case 0:
3887820Sroot 		if (subyte(iov->iov_base, c) < 0)
3897820Sroot 			return (EFAULT);
3907820Sroot 		break;
3917820Sroot 
3927820Sroot 	case 1:
3937820Sroot 		*iov->iov_base = c;
3947820Sroot 		break;
3957820Sroot 
3967820Sroot 	case 2:
3977820Sroot 		if (suibyte(iov->iov_base, c) < 0)
3987820Sroot 			return (EFAULT);
3997820Sroot 		break;
4007820Sroot 	}
4017820Sroot 	iov->iov_base++;
4027820Sroot 	iov->iov_len--;
4037820Sroot 	uio->uio_resid--;
4047820Sroot 	uio->uio_offset++;
4057820Sroot 	return (0);
4067820Sroot }
4077820Sroot 
4087820Sroot /*
4097820Sroot  * Get next character written in by user from uio.
4107820Sroot  */
4117820Sroot uwritec(uio)
4127820Sroot 	struct uio *uio;
4137820Sroot {
4147820Sroot 	register struct iovec *iov;
4157820Sroot 	register int c;
4167820Sroot 
4177820Sroot again:
4187820Sroot 	if (uio->uio_iovcnt <= 0 || uio->uio_resid <= 0)
4197820Sroot 		panic("uwritec");
4207820Sroot 	iov = uio->uio_iov;
4217820Sroot 	if (iov->iov_len == 0) {
4227820Sroot 		uio->uio_iovcnt--;
4237820Sroot 		uio->uio_iov++;
4247820Sroot 		goto again;
4257820Sroot 	}
4267820Sroot 	switch (uio->uio_segflg) {
4277820Sroot 
4287820Sroot 	case 0:
4297820Sroot 		c = fubyte(iov->iov_base);
4307820Sroot 		break;
4317820Sroot 
4327820Sroot 	case 1:
4337820Sroot 		c = *iov->iov_base & 0377;
4347820Sroot 		break;
4357820Sroot 
4367820Sroot 	case 2:
4377820Sroot 		c = fuibyte(iov->iov_base);
4387820Sroot 		break;
4397820Sroot 	}
4407820Sroot 	if (c < 0)
4417820Sroot 		return (-1);
4427820Sroot 	iov->iov_base++;
4437820Sroot 	iov->iov_len--;
4447820Sroot 	uio->uio_resid--;
4457820Sroot 	uio->uio_offset++;
4467820Sroot 	return (c & 0377);
4477820Sroot }
4487820Sroot 
4497820Sroot /*
4507423Sroot  * Ioctl system call
4517624Ssam  * Check legality, execute common code,
4527624Ssam  * and switch out to individual device routine.
4537423Sroot  */
4547423Sroot ioctl()
4557423Sroot {
4567423Sroot 	register struct file *fp;
4577624Ssam 	struct a {
4587423Sroot 		int	fdes;
4597423Sroot 		int	cmd;
4607423Sroot 		caddr_t	cmarg;
4617423Sroot 	} *uap;
4627820Sroot 	register int com;
4637820Sroot 	register u_int size;
4647624Ssam 	char data[IOCPARM_MASK+1];
4657423Sroot 
4667423Sroot 	uap = (struct a *)u.u_ap;
4677423Sroot 	if ((fp = getf(uap->fdes)) == NULL)
4687423Sroot 		return;
4697423Sroot 	if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
4707423Sroot 		u.u_error = EBADF;
4717423Sroot 		return;
4727423Sroot 	}
4737624Ssam 	com = uap->cmd;
4747624Ssam 
4757699Ssam #ifndef NOCOMPAT
4767624Ssam 	/*
4777624Ssam 	 * Map old style ioctl's into new for the
4787624Ssam 	 * sake of backwards compatibility (sigh).
4797624Ssam 	 */
4807624Ssam 	if ((com&~0xffff) == 0) {
4817624Ssam 		com = mapioctl(com);
4827624Ssam 		if (com == 0) {
4837624Ssam 			u.u_error = EINVAL;
4847624Ssam 			return;
4857624Ssam 		}
4867624Ssam 	}
4877624Ssam #endif
4887624Ssam 	if (com == FIOCLEX) {
4897423Sroot 		u.u_pofile[uap->fdes] |= EXCLOSE;
4907423Sroot 		return;
4917423Sroot 	}
4927624Ssam 	if (com == FIONCLEX) {
4937423Sroot 		u.u_pofile[uap->fdes] &= ~EXCLOSE;
4947423Sroot 		return;
4957423Sroot 	}
4967624Ssam 
4977624Ssam 	/*
4987624Ssam 	 * Interpret high order word to find
4997624Ssam 	 * amount of data to be copied to/from the
5007624Ssam 	 * user's address space.
5017624Ssam 	 */
5027624Ssam 	size = (com &~ (IOC_INOUT|IOC_VOID)) >> 16;
5037624Ssam 	if (size > sizeof (data)) {
5047624Ssam 		u.u_error = EFAULT;
5057423Sroot 		return;
5067423Sroot 	}
5077699Ssam 	if (com&IOC_IN && size) {
5087820Sroot 		if (copyin(uap->cmarg, (caddr_t)data, (u_int)size)) {
5097624Ssam 			u.u_error = EFAULT;
5107624Ssam 			return;
5117624Ssam 		}
5127624Ssam 	} else
5137624Ssam 		*(caddr_t *)data = uap->cmarg;
5147624Ssam 	/*
5157624Ssam 	 * Zero the buffer on the stack so the user
5167624Ssam 	 * always gets back something deterministic.
5177624Ssam 	 */
5187624Ssam 	if ((com&IOC_OUT) && size)
5197624Ssam 		bzero((caddr_t)data, size);
5207423Sroot 
5217624Ssam 	if (fp->f_type == DTYPE_SOCKET)
5227624Ssam 		soioctl(fp->f_socket, com, data);
5237624Ssam 	else {
5247624Ssam 		register struct inode *ip = fp->f_inode;
5257624Ssam 		int fmt = ip->i_mode & IFMT;
5267624Ssam 		dev_t dev;
5277624Ssam 
5287624Ssam 		if (fmt != IFCHR) {
5297624Ssam 			if (com == FIONREAD && (fmt == IFREG || fmt == IFDIR)) {
5307624Ssam 				*(off_t *)data = ip->i_size - fp->f_offset;
5317624Ssam 				goto returndata;
5327624Ssam 			}
5337624Ssam 			if (com != FIONBIO && com != FIOASYNC)
5347624Ssam 				u.u_error = ENOTTY;
5357423Sroot 			return;
5367624Ssam 		}
5377624Ssam 		dev = ip->i_rdev;
5387624Ssam 		u.u_r.r_val1 = 0;
539*8118Sroot 		if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) {
5407624Ssam 			u.u_eosys = RESTARTSYS;
5417624Ssam 			return;
5427624Ssam 		}
5437624Ssam 		(*cdevsw[major(dev)].d_ioctl)(dev, com, data, 0);
5447423Sroot 	}
5457624Ssam 
5467624Ssam returndata:
5477624Ssam 	/*
5487624Ssam 	 * Copy any data to user, size was
5497624Ssam 	 * already set and checked above.
5507624Ssam 	 */
5517820Sroot 	if (u.u_error == 0 && (com&IOC_OUT))
5527820Sroot 		if (size && copyout(data, uap->cmarg, (u_int)size))
5537699Ssam 			u.u_error = EFAULT;
5547423Sroot }
5557423Sroot 
5567423Sroot /*
5577423Sroot  * Do nothing specific version of line
5587423Sroot  * discipline specific ioctl command.
5597423Sroot  */
5607423Sroot /*ARGSUSED*/
5617624Ssam nullioctl(tp, cmd, data, flags)
5627423Sroot 	struct tty *tp;
5637624Ssam 	char *data;
5647624Ssam 	int flags;
5657423Sroot {
5667423Sroot 
5677624Ssam #ifdef lint
5687624Ssam 	tp = tp; data = data; flags = flags;
5697624Ssam #endif
5707423Sroot 	return (cmd);
5717423Sroot }
5728103Sroot 
5738103Sroot ostty()
5748103Sroot {
5758103Sroot 
5768103Sroot }
5778103Sroot 
5788103Sroot ogtty()
5798103Sroot {
5808103Sroot 
5818103Sroot }
582