1 /* kern_descrip.c 5.1 82/07/15 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/reg.h" 8 #include "../h/inode.h" 9 #include "../h/proc.h" 10 #include "../h/clock.h" 11 #include "../h/mtpr.h" 12 #include "../h/timeb.h" 13 #include "../h/times.h" 14 #include "../h/reboot.h" 15 #include "../h/fs.h" 16 #include "../h/conf.h" 17 #include "../h/buf.h" 18 #include "../h/mount.h" 19 #include "../h/file.h" 20 #include "../h/inline.h" 21 #include "../h/socket.h" 22 #include "../h/socketvar.h" 23 24 /* 25 * the dup system call. 26 */ 27 dup() 28 { 29 register struct file *fp; 30 register struct a { 31 int fdes; 32 int fdes2; 33 } *uap; 34 register i, m; 35 36 uap = (struct a *)u.u_ap; 37 m = uap->fdes & ~077; 38 uap->fdes &= 077; 39 fp = getf(uap->fdes); 40 if (fp == NULL) 41 return; 42 if ((m&0100) == 0) { 43 if ((i = ufalloc()) < 0) 44 return; 45 } else { 46 i = uap->fdes2; 47 if (i<0 || i>=NOFILE) { 48 u.u_error = EBADF; 49 return; 50 } 51 u.u_r.r_val1 = i; 52 } 53 if (i != uap->fdes) { 54 if (u.u_ofile[i]!=NULL) 55 closef(u.u_ofile[i], 0); 56 if (u.u_error) 57 return; 58 u.u_ofile[i] = fp; 59 fp->f_count++; 60 } 61 } 62 63 int nselcoll; 64 /* 65 * Select system call. 66 */ 67 select() 68 { 69 register struct uap { 70 int nfd; 71 fd_set *rp, *wp; 72 int timo; 73 } *ap = (struct uap *)u.u_ap; 74 fd_set rd, wr; 75 int nfds = 0, readable = 0, writeable = 0; 76 time_t t = time; 77 int s, tsel, ncoll, rem; 78 79 if (ap->nfd > NOFILE) 80 ap->nfd = NOFILE; 81 if (ap->nfd < 0) { 82 u.u_error = EBADF; 83 return; 84 } 85 if (ap->rp && copyin((caddr_t)ap->rp,(caddr_t)&rd,sizeof(fd_set))) 86 return; 87 if (ap->wp && copyin((caddr_t)ap->wp,(caddr_t)&wr,sizeof(fd_set))) 88 return; 89 retry: 90 ncoll = nselcoll; 91 u.u_procp->p_flag |= SSEL; 92 if (ap->rp) 93 readable = selscan(ap->nfd, rd, &nfds, FREAD); 94 if (ap->wp) 95 writeable = selscan(ap->nfd, wr, &nfds, FWRITE); 96 if (u.u_error) 97 goto done; 98 if (readable || writeable) 99 goto done; 100 rem = (ap->timo+999)/1000 - (time - t); 101 if (ap->timo == 0 || rem <= 0) 102 goto done; 103 s = spl6(); 104 if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) { 105 u.u_procp->p_flag &= ~SSEL; 106 splx(s); 107 goto retry; 108 } 109 u.u_procp->p_flag &= ~SSEL; 110 tsel = tsleep((caddr_t)&selwait, PZERO+1, rem); 111 splx(s); 112 switch (tsel) { 113 114 case TS_OK: 115 goto retry; 116 117 case TS_SIG: 118 u.u_error = EINTR; 119 return; 120 121 case TS_TIME: 122 break; 123 } 124 done: 125 rd.fds_bits[0] = readable; 126 wr.fds_bits[0] = writeable; 127 s = sizeof (fd_set); 128 if (s * NBBY > ap->nfd) 129 s = (ap->nfd + NBBY - 1) / NBBY; 130 u.u_r.r_val1 = nfds; 131 if (ap->rp) 132 (void) copyout((caddr_t)&rd, (caddr_t)ap->rp, sizeof(fd_set)); 133 if (ap->wp) 134 (void) copyout((caddr_t)&wr, (caddr_t)ap->wp, sizeof(fd_set)); 135 } 136 137 selscan(nfd, fds, nfdp, flag) 138 int nfd; 139 fd_set fds; 140 int *nfdp, flag; 141 { 142 struct file *fp; 143 struct inode *ip; 144 register int bits; 145 int i, able, res = 0; 146 147 bits = fds.fds_bits[0]; 148 while (i = ffs(bits)) { 149 if (i > nfd) 150 break; 151 bits &= ~(1<<(i-1)); 152 fp = u.u_ofile[i-1]; 153 if (fp == NULL) { 154 u.u_error = EBADF; 155 return (0); 156 } 157 if (fp->f_flag & FSOCKET) 158 able = soselect(fp->f_socket, flag); 159 else { 160 ip = fp->f_inode; 161 switch (ip->i_mode & IFMT) { 162 163 case IFCHR: 164 able = 165 (*cdevsw[major(ip->i_rdev)].d_select) 166 (ip->i_rdev, flag); 167 break; 168 169 case IFBLK: 170 case IFREG: 171 case IFDIR: 172 able = 1; 173 break; 174 } 175 } 176 if (able) { 177 res |= (1<<(i-1)); 178 (*nfdp)++; 179 } 180 } 181 return (res); 182 } 183 184 /*ARGSUSED*/ 185 seltrue(dev, flag) 186 dev_t dev; 187 int flag; 188 { 189 190 return (1); 191 } 192 193 selwakeup(p, coll) 194 register struct proc *p; 195 int coll; 196 { 197 int s; 198 199 if (coll) { 200 nselcoll++; 201 wakeup((caddr_t)&selwait); 202 } 203 if (p) { 204 if (p->p_wchan == (caddr_t)&selwait) 205 setrun(p); 206 else { 207 s = spl6(); 208 if (p->p_flag & SSEL) 209 p->p_flag &= ~SSEL; 210 splx(s); 211 } 212 } 213 } 214 215 /* 216 * Close system call 217 */ 218 close() 219 { 220 register struct file *fp; 221 register struct a { 222 int fdes; 223 } *uap; 224 225 uap = (struct a *)u.u_ap; 226 fp = getf(uap->fdes); 227 if (fp == NULL) 228 return; 229 if (u.u_vrpages[uap->fdes]) { 230 u.u_error = ETXTBSY; 231 return; 232 } 233 u.u_ofile[uap->fdes] = NULL; 234 closef(fp, 0); 235 } 236