-/* kern_descrip.c 5.4 82/08/10 */
+/* kern_descrip.c 5.23 83/01/17 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/dir.h"
#include "../h/user.h"
+#include "../h/kernel.h"
#include "../h/inode.h"
#include "../h/proc.h"
#include "../h/conf.h"
#include "../h/file.h"
-#include "../h/inline.h"
#include "../h/socket.h"
#include "../h/socketvar.h"
#include "../h/mount.h"
/*
* System calls on descriptors.
*/
-dstd()
+getdtablesize()
{
u.u_r.r_val1 = NOFILE;
}
+getdprop()
+{
+ register struct a {
+ int d;
+ struct dtype *dtypeb;
+ } *uap = (struct a *)u.u_ap;
+ register struct file *fp;
+ struct dtype adtype;
+
+ fp = getf(uap->d);
+ if (fp == 0)
+ return;
+ adtype.dt_type = 0; /* XXX */
+ adtype.dt_protocol = 0; /* XXX */
+ u.u_error = copyout((caddr_t)&adtype, (caddr_t)uap->dtypeb,
+ sizeof (struct dtype));
+ if (u.u_error)
+ return;
+}
+
+getdopt()
+{
+
+}
+
+setdopt()
+{
+
+}
+
dup()
{
register struct a {
j = ufalloc();
if (j < 0)
return;
- dupit(j, fp, u.u_pofile[uap->i] & (RDLOCK|WRLOCK));
+ dupit(j, fp, u.u_pofile[uap->i] & (UF_SHLOCK|UF_EXLOCK));
}
dup2()
if (uap->i == uap->j)
return;
if (u.u_ofile[uap->j]) {
+ if (u.u_pofile[uap->j] & UF_MAPPED)
+ munmapfd(uap->j);
closef(u.u_ofile[uap->j], 0, u.u_pofile[uap->j]);
if (u.u_error)
return;
/* u.u_ofile[uap->j] = 0; */
/* u.u_pofile[uap->j] = 0; */
}
- dupit(uap->j, fp, u.u_pofile[uap->i] & (RDLOCK|WRLOCK));
+ dupit(uap->j, fp, u.u_pofile[uap->i] & (UF_SHLOCK|UF_EXLOCK));
}
dupit(fd, fp, lockflags)
u.u_ofile[fd] = fp;
u.u_pofile[fd] = lockflags;
fp->f_count++;
- if (lockflags&RDLOCK)
- fp->f_inode->i_rdlockc++;
- if (lockflags&WRLOCK)
- fp->f_inode->i_wrlockc++;
+ if (lockflags&UF_SHLOCK)
+ fp->f_inode->i_shlockc++;
+ if (lockflags&UF_EXLOCK)
+ fp->f_inode->i_exlockc++;
}
close()
fp = getf(uap->i);
if (fp == 0)
return;
+ if (u.u_pofile[uap->i] & UF_MAPPED)
+ munmapfd(uap->i);
closef(fp, 0, u.u_pofile[uap->i]);
/* WHAT IF u.u_error ? */
u.u_ofile[uap->i] = NULL;
u.u_pofile[uap->i] = 0;
}
-dtype()
+wrap()
{
register struct a {
int d;
fp = getf(uap->d);
if (fp == 0)
return;
- adtype.dt_type = 0; /* XXX */
- adtype.dt_protocol = 0; /* XXX */
- if (copyout((caddr_t)&adtype, (caddr_t)uap->dtypeb,
- sizeof (struct dtype)) < 0) {
- u.u_error = EFAULT;
- return;
- }
-}
-
-dwrap()
-{
- register struct a {
- int d;
- struct dtype *dtypeb;
- } *uap = (struct a *)u.u_ap;
- register struct file *fp;
- struct dtype adtype;
-
- fp = getf(uap->d);
- if (fp == 0)
- return;
- if (copyin((caddr_t)uap->dtypeb, (caddr_t)&adtype,
- sizeof (struct dtype)) < 0) {
- u.u_error = EFAULT;
+ u.u_error = copyin((caddr_t)uap->dtypeb, (caddr_t)&adtype,
+ sizeof (struct dtype));
+ if (u.u_error)
return;
- }
/* DO WRAP */
}
-dselect()
-{
-
-}
-
-dnblock()
-{
- register struct a {
- int d;
- int how;
- } *uap = (struct a *)u.u_ap;
-
- /* XXX */
-}
-
-dsignal()
-{
- register struct a {
- int d;
- int how;
- } *uap = (struct a *)u.u_ap;
-
- /* XXX */
-}
-
+int unselect();
int nselcoll;
/*
* Select system call.
*/
-oselect()
+select()
{
register struct uap {
- int nfd;
- fd_set *rp, *wp;
- int timo;
- } *ap = (struct uap *)u.u_ap;
- fd_set rd, wr;
- int nfds = 0, readable = 0, writeable = 0;
- time_t t = time;
- int s, tsel, ncoll, rem;
-
- if (ap->nfd > NOFILE)
- ap->nfd = NOFILE;
- if (ap->nfd < 0) {
- u.u_error = EBADF;
- return;
+ int nd;
+ long *in;
+ long *ou;
+ long *ex;
+ struct timeval *tv;
+ } *uap = (struct uap *)u.u_ap;
+ int ibits[3], obits[3];
+ struct timeval atv;
+ int s, ncoll;
+ label_t lqsave;
+
+ obits[0] = obits[1] = obits[2] = 0;
+ if (uap->nd > NOFILE)
+ uap->nd = NOFILE; /* forgiving, if slightly wrong */
+
+#define getbits(name, x) \
+ if (uap->name) { \
+ u.u_error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \
+ sizeof (ibits[x])); \
+ if (u.u_error) \
+ goto done; \
+ } else \
+ ibits[x] = 0;
+ getbits(in, 0);
+ getbits(ou, 1);
+ getbits(ex, 2);
+#undef getbits
+
+ if (uap->tv) {
+ u.u_error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
+ sizeof (atv));
+ if (u.u_error)
+ goto done;
+ if (itimerfix(&atv)) {
+ u.u_error = EINVAL;
+ goto done;
+ }
+ s = spl7(); timevaladd(&atv, &time); splx(s);
}
- if (ap->rp && copyin((caddr_t)ap->rp,(caddr_t)&rd,sizeof(fd_set)))
- return;
- if (ap->wp && copyin((caddr_t)ap->wp,(caddr_t)&wr,sizeof(fd_set)))
- return;
retry:
ncoll = nselcoll;
u.u_procp->p_flag |= SSEL;
- if (ap->rp)
- readable = selscan(ap->nfd, rd, &nfds, FREAD);
- if (ap->wp)
- writeable = selscan(ap->nfd, wr, &nfds, FWRITE);
- if (u.u_error)
- goto done;
- if (readable || writeable)
- goto done;
- rem = (ap->timo+999)/1000 - (time - t);
- if (ap->timo == 0 || rem <= 0)
+ u.u_r.r_val1 = selscan(ibits, obits);
+ if (u.u_error || u.u_r.r_val1)
goto done;
s = spl6();
+ if (uap->tv && timercmp(&time, &atv, >=)) {
+ splx(s);
+ goto done;
+ }
if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) {
u.u_procp->p_flag &= ~SSEL;
splx(s);
goto retry;
}
u.u_procp->p_flag &= ~SSEL;
- tsel = tsleep((caddr_t)&selwait, PZERO+1, rem);
+ if (uap->tv) {
+ lqsave = u.u_qsave;
+ if (setjmp(&u.u_qsave)) {
+ untimeout(unselect, (caddr_t)u.u_procp);
+ u.u_error = EINTR;
+ splx(s);
+ goto done;
+ }
+ timeout(unselect, (caddr_t)u.u_procp, hzto(&atv));
+ }
+ sleep((caddr_t)&selwait, PZERO+1);
+ if (uap->tv) {
+ u.u_qsave = lqsave;
+ untimeout(unselect, (caddr_t)u.u_procp);
+ }
splx(s);
- switch (tsel) {
+ goto retry;
+done:
+#define putbits(name, x) \
+ if (uap->name) { \
+ int error = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \
+ sizeof (obits[x])); \
+ if (error) \
+ u.u_error = error; \
+ }
+ putbits(in, 0);
+ putbits(ou, 1);
+ putbits(ex, 2);
+#undef putbits
+}
- case TS_OK:
- goto retry;
+unselect(p)
+ register struct proc *p;
+{
+ register int s = spl6();
- case TS_SIG:
- u.u_error = EINTR;
- return;
+ switch (p->p_stat) {
+
+ case SSLEEP:
+ setrun(p);
+ break;
- case TS_TIME:
+ case SSTOP:
+ unsleep(p);
break;
}
-done:
- rd.fds_bits[0] = readable;
- wr.fds_bits[0] = writeable;
- s = sizeof (fd_set);
- if (s * NBBY > ap->nfd)
- s = (ap->nfd + NBBY - 1) / NBBY;
- u.u_r.r_val1 = nfds;
- if (ap->rp)
- (void) copyout((caddr_t)&rd, (caddr_t)ap->rp, sizeof(fd_set));
- if (ap->wp)
- (void) copyout((caddr_t)&wr, (caddr_t)ap->wp, sizeof(fd_set));
+ splx(s);
}
-selscan(nfd, fds, nfdp, flag)
- int nfd;
- fd_set fds;
- int *nfdp, flag;
+selscan(ibits, obits)
+ int *ibits, *obits;
{
+ register int which, bits, i;
+ int flag;
struct file *fp;
+ int able;
struct inode *ip;
- register int bits;
- int i, able, res = 0;
-
- bits = fds.fds_bits[0];
- while (i = ffs(bits)) {
- if (i > nfd)
- break;
- bits &= ~(1<<(i-1));
- fp = u.u_ofile[i-1];
- if (fp == NULL) {
- u.u_error = EBADF;
- return (0);
- }
- if (fp->f_type == DTYPE_SOCKET)
- able = soselect(fp->f_socket, flag);
- else {
- ip = fp->f_inode;
- switch (ip->i_mode & IFMT) {
-
- case IFCHR:
- able =
- (*cdevsw[major(ip->i_rdev)].d_select)
- (ip->i_rdev, flag);
- break;
+ int n = 0;
+
+ for (which = 0; which < 3; which++) {
+ bits = ibits[which];
+ obits[which] = 0;
+ switch (which) {
+
+ case 0:
+ flag = FREAD; break;
- case IFBLK:
- case IFREG:
- case IFDIR:
- able = 1;
+ case 1:
+ flag = FWRITE; break;
+
+ case 2:
+ flag = 0; break;
+ }
+ while (i = ffs(bits)) {
+ bits &= ~(1<<(i-1));
+ fp = u.u_ofile[i-1];
+ if (fp == NULL) {
+ u.u_error = EBADF;
break;
}
+ if (fp->f_type == DTYPE_SOCKET)
+ able = soselect(fp->f_socket, flag);
+ else {
+ ip = fp->f_inode;
+ switch (ip->i_mode & IFMT) {
+
+ case IFCHR:
+ able =
+ (*cdevsw[major(ip->i_rdev)].d_select)
+ (ip->i_rdev, flag);
+ break;
+
+ case IFBLK:
+ case IFREG:
+ case IFDIR:
+ able = 1;
+ break;
+ }
- }
- if (able) {
- res |= (1<<(i-1));
- (*nfdp)++;
+ }
+ if (able) {
+ obits[which] |= (1<<(i-1));
+ n++;
+ }
}
}
- return (res);
+ return (n);
}
/*ARGSUSED*/
register struct proc *p;
int coll;
{
- int s;
if (coll) {
nselcoll++;
wakeup((caddr_t)&selwait);
}
if (p) {
+ int s = spl6();
if (p->p_wchan == (caddr_t)&selwait)
setrun(p);
- else {
- s = spl6();
- if (p->p_flag & SSEL)
- p->p_flag &= ~SSEL;
- splx(s);
- }
+ else if (p->p_flag & SSEL)
+ p->p_flag &= ~SSEL;
+ splx(s);
}
}
+revoke()
+{
+
+ /* XXX */
+}
+
/*
* Allocate a user file descriptor.
*/
return;
}
if (fp->f_type == DTYPE_SOCKET) {
- u.u_error = 0; /* XXX */
- soclose(fp->f_socket, nouser);
+ u.u_error = soclose(fp->f_socket, nouser);
if (nouser == 0 && u.u_error)
return;
fp->f_socket = 0;
ip = fp->f_inode;
dev = (dev_t)ip->i_rdev;
mode = ip->i_mode & IFMT;
- flags &= RDLOCK|WRLOCK; /* conservative */
+ flags &= UF_SHLOCK|UF_EXLOCK; /* conservative */
if (flags)
funlocki(ip, flags);
ilock(ip);
}
(*cfunc)(dev, flag, fp);
}
+
+opause()
+{
+
+ for (;;)
+ sleep((caddr_t)&u, PSLEP);
+}