BBN-Vax-TCP/sys/ioctl.c
/* ioctl.c 4.4 81/03/08 */
/*
* Ioctl.
*/
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/tty.h"
#include "../h/proc.h"
#include "../h/inode.h"
#include "../h/file.h"
#include "../h/conf.h"
/*
* stty/gtty writearound
*/
stty()
{
u.u_arg[2] = u.u_arg[1];
u.u_arg[1] = TIOCSETP;
ioctl();
}
gtty()
{
u.u_arg[2] = u.u_arg[1];
u.u_arg[1] = TIOCGETP;
ioctl();
}
/*
* ioctl system call
* Check legality, execute common code, and switch out to individual
* device routine.
*/
ioctl()
{
register struct file *fp;
register struct inode *ip;
register struct a {
int fdes;
int cmd;
caddr_t cmarg;
} *uap;
register dev_t dev;
register fmt;
uap = (struct a *)u.u_ap;
if ((fp = getf(uap->fdes)) == NULL)
return;
if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
u.u_error = EBADF;
return;
}
if (uap->cmd==FIOCLEX) {
u.u_pofile[uap->fdes] |= EXCLOSE;
return;
}
if (uap->cmd==FIONCLEX) {
u.u_pofile[uap->fdes] &= ~EXCLOSE;
return;
}
#ifdef BBNNET
if (fp->f_flag & FNET) {
netioctl(fp->f_un.f_ucb, uap->cmd, uap->cmarg);
return;
}
#endif BBNNET
ip = fp->f_inode;
fmt = ip->i_mode & IFMT;
if (fmt != IFCHR && fmt != IFMPC) {
/* begin local */
if (uap->cmd==FIONREAD && (fmt == IFREG || fmt == IFDIR)) {
off_t nread = ip->i_size - fp->f_un.f_offset;
if (copyout((caddr_t)&nread, uap->cmarg, sizeof(off_t)))
u.u_error = EFAULT;
} else
/* end local */
u.u_error = ENOTTY;
return;
}
dev = ip->i_un.i_rdev;
u.u_r.r_val1 = 0;
if ((u.u_procp->p_flag&SNUSIG) && setjmp(u.u_qsav)) {
u.u_eosys = RESTARTSYS;
return;
}
(*cdevsw[major(dev)].d_ioctl)(dev, uap->cmd, uap->cmarg, 0);
}
/*
* Do nothing specific version of line
* discipline specific ioctl command.
*/
/*ARGSUSED*/
nullioctl(tp, cmd, addr)
struct tty *tp;
caddr_t addr;
{
return (cmd);
}