xref: /freebsd/sys/kern/sys_generic.c (revision 0c43d89a0d8e976ca494d4837f4c1f3734d2c300)
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *	@(#)sys_generic.c	8.5 (Berkeley) 1/21/94
39  * $Id$
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/filedesc.h>
45 #include <sys/ioctl.h>
46 #include <sys/file.h>
47 #include <sys/proc.h>
48 #include <sys/socketvar.h>
49 #include <sys/uio.h>
50 #include <sys/kernel.h>
51 #include <sys/stat.h>
52 #include <sys/malloc.h>
53 #ifdef KTRACE
54 #include <sys/ktrace.h>
55 #endif
56 
57 /*
58  * Read system call.
59  */
60 struct read_args {
61 	int	fd;
62 	char	*buf;
63 	u_int	nbyte;
64 };
65 /* ARGSUSED */
66 int
67 read(p, uap, retval)
68 	struct proc *p;
69 	register struct read_args *uap;
70 	int *retval;
71 {
72 	register struct file *fp;
73 	register struct filedesc *fdp = p->p_fd;
74 	struct uio auio;
75 	struct iovec aiov;
76 	long cnt, error = 0;
77 #ifdef KTRACE
78 	struct iovec ktriov;
79 #endif
80 
81 	if (((u_int)uap->fd) >= fdp->fd_nfiles ||
82 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL ||
83 	    (fp->f_flag & FREAD) == 0)
84 		return (EBADF);
85 	aiov.iov_base = (caddr_t)uap->buf;
86 	aiov.iov_len = uap->nbyte;
87 	auio.uio_iov = &aiov;
88 	auio.uio_iovcnt = 1;
89 	auio.uio_resid = uap->nbyte;
90 	auio.uio_rw = UIO_READ;
91 	auio.uio_segflg = UIO_USERSPACE;
92 	auio.uio_procp = p;
93 #ifdef KTRACE
94 	/*
95 	 * if tracing, save a copy of iovec
96 	 */
97 	if (KTRPOINT(p, KTR_GENIO))
98 		ktriov = aiov;
99 #endif
100 	cnt = uap->nbyte;
101 	if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))
102 		if (auio.uio_resid != cnt && (error == ERESTART ||
103 		    error == EINTR || error == EWOULDBLOCK))
104 			error = 0;
105 	cnt -= auio.uio_resid;
106 #ifdef KTRACE
107 	if (KTRPOINT(p, KTR_GENIO) && error == 0)
108 		ktrgenio(p->p_tracep, uap->fd, UIO_READ, &ktriov, cnt, error);
109 #endif
110 	*retval = cnt;
111 	return (error);
112 }
113 
114 /*
115  * Scatter read system call.
116  */
117 struct readv_args {
118 	int	fdes;
119 	struct	iovec *iovp;
120 	u_int	iovcnt;
121 };
122 int
123 readv(p, uap, retval)
124 	struct proc *p;
125 	register struct readv_args *uap;
126 	int *retval;
127 {
128 	register struct file *fp;
129 	register struct filedesc *fdp = p->p_fd;
130 	struct uio auio;
131 	register struct iovec *iov;
132 	struct iovec *needfree;
133 	struct iovec aiov[UIO_SMALLIOV];
134 	long i, cnt, error = 0;
135 	u_int iovlen;
136 #ifdef KTRACE
137 	struct iovec *ktriov = NULL;
138 #endif
139 
140 	if (((u_int)uap->fdes) >= fdp->fd_nfiles ||
141 	    (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
142 	    (fp->f_flag & FREAD) == 0)
143 		return (EBADF);
144 	/* note: can't use iovlen until iovcnt is validated */
145 	iovlen = uap->iovcnt * sizeof (struct iovec);
146 	if (uap->iovcnt > UIO_SMALLIOV) {
147 		if (uap->iovcnt > UIO_MAXIOV)
148 			return (EINVAL);
149 		MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
150 		needfree = iov;
151 	} else {
152 		iov = aiov;
153 		needfree = NULL;
154 	}
155 	auio.uio_iov = iov;
156 	auio.uio_iovcnt = uap->iovcnt;
157 	auio.uio_rw = UIO_READ;
158 	auio.uio_segflg = UIO_USERSPACE;
159 	auio.uio_procp = p;
160 	if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))
161 		goto done;
162 	auio.uio_resid = 0;
163 	for (i = 0; i < uap->iovcnt; i++) {
164 		auio.uio_resid += iov->iov_len;
165 		if (auio.uio_resid < 0) {
166 			error = EINVAL;
167 			goto done;
168 		}
169 		iov++;
170 	}
171 #ifdef KTRACE
172 	/*
173 	 * if tracing, save a copy of iovec
174 	 */
175 	if (KTRPOINT(p, KTR_GENIO))  {
176 		MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
177 		bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
178 	}
179 #endif
180 	cnt = auio.uio_resid;
181 	if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))
182 		if (auio.uio_resid != cnt && (error == ERESTART ||
183 		    error == EINTR || error == EWOULDBLOCK))
184 			error = 0;
185 	cnt -= auio.uio_resid;
186 #ifdef KTRACE
187 	if (ktriov != NULL) {
188 		if (error == 0)
189 			ktrgenio(p->p_tracep, uap->fdes, UIO_READ, ktriov,
190 			    cnt, error);
191 		FREE(ktriov, M_TEMP);
192 	}
193 #endif
194 	*retval = cnt;
195 done:
196 	if (needfree)
197 		FREE(needfree, M_IOV);
198 	return (error);
199 }
200 
201 /*
202  * Write system call
203  */
204 struct write_args {
205 	int	fd;
206 	char	*buf;
207 	u_int	nbyte;
208 };
209 int
210 write(p, uap, retval)
211 	struct proc *p;
212 	register struct write_args *uap;
213 	int *retval;
214 {
215 	register struct file *fp;
216 	register struct filedesc *fdp = p->p_fd;
217 	struct uio auio;
218 	struct iovec aiov;
219 	long cnt, error = 0;
220 	int i;
221 #ifdef KTRACE
222 	struct iovec ktriov;
223 #endif
224 
225 	if (((u_int)uap->fd) >= fdp->fd_nfiles ||
226 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL ||
227 	    (fp->f_flag & FWRITE) == 0)
228 		return (EBADF);
229 	aiov.iov_base = (caddr_t)uap->buf;
230 	aiov.iov_len = uap->nbyte;
231 	auio.uio_iov = &aiov;
232 	auio.uio_iovcnt = 1;
233 	auio.uio_resid = uap->nbyte;
234 	auio.uio_rw = UIO_WRITE;
235 	auio.uio_segflg = UIO_USERSPACE;
236 	auio.uio_procp = p;
237 #ifdef KTRACE
238 	/*
239 	 * if tracing, save a copy of iovec
240 	 */
241 	if (KTRPOINT(p, KTR_GENIO))
242 		ktriov = aiov;
243 #endif
244 	cnt = uap->nbyte;
245 	if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) {
246 		if (auio.uio_resid != cnt && (error == ERESTART ||
247 		    error == EINTR || error == EWOULDBLOCK))
248 			error = 0;
249 		if (error == EPIPE)
250 			psignal(p, SIGPIPE);
251 	}
252 	cnt -= auio.uio_resid;
253 #ifdef KTRACE
254 	if (KTRPOINT(p, KTR_GENIO) && error == 0)
255 		ktrgenio(p->p_tracep, uap->fd, UIO_WRITE,
256 		    &ktriov, cnt, error);
257 #endif
258 	*retval = cnt;
259 	return (error);
260 }
261 
262 /*
263  * Gather write system call
264  */
265 struct writev_args {
266 	int	fd;
267 	struct	iovec *iovp;
268 	u_int	iovcnt;
269 };
270 int
271 writev(p, uap, retval)
272 	struct proc *p;
273 	register struct writev_args *uap;
274 	int *retval;
275 {
276 	register struct file *fp;
277 	register struct filedesc *fdp = p->p_fd;
278 	struct uio auio;
279 	register struct iovec *iov;
280 	struct iovec *needfree;
281 	struct iovec aiov[UIO_SMALLIOV];
282 	long i, cnt, error = 0;
283 	u_int iovlen;
284 #ifdef KTRACE
285 	struct iovec *ktriov = NULL;
286 #endif
287 
288 	if (((u_int)uap->fd) >= fdp->fd_nfiles ||
289 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL ||
290 	    (fp->f_flag & FWRITE) == 0)
291 		return (EBADF);
292 	/* note: can't use iovlen until iovcnt is validated */
293 	iovlen = uap->iovcnt * sizeof (struct iovec);
294 	if (uap->iovcnt > UIO_SMALLIOV) {
295 		if (uap->iovcnt > UIO_MAXIOV)
296 			return (EINVAL);
297 		MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
298 		needfree = iov;
299 	} else {
300 		iov = aiov;
301 		needfree = NULL;
302 	}
303 	auio.uio_iov = iov;
304 	auio.uio_iovcnt = uap->iovcnt;
305 	auio.uio_rw = UIO_WRITE;
306 	auio.uio_segflg = UIO_USERSPACE;
307 	auio.uio_procp = p;
308 	if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))
309 		goto done;
310 	auio.uio_resid = 0;
311 	for (i = 0; i < uap->iovcnt; i++) {
312 		auio.uio_resid += iov->iov_len;
313 		if (auio.uio_resid < 0) {
314 			error = EINVAL;
315 			goto done;
316 		}
317 		iov++;
318 	}
319 #ifdef KTRACE
320 	/*
321 	 * if tracing, save a copy of iovec
322 	 */
323 	if (KTRPOINT(p, KTR_GENIO))  {
324 		MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
325 		bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
326 	}
327 #endif
328 	cnt = auio.uio_resid;
329 	if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) {
330 		if (auio.uio_resid != cnt && (error == ERESTART ||
331 		    error == EINTR || error == EWOULDBLOCK))
332 			error = 0;
333 		if (error == EPIPE)
334 			psignal(p, SIGPIPE);
335 	}
336 	cnt -= auio.uio_resid;
337 #ifdef KTRACE
338 	if (ktriov != NULL) {
339 		if (error == 0)
340 			ktrgenio(p->p_tracep, uap->fd, UIO_WRITE,
341 				ktriov, cnt, error);
342 		FREE(ktriov, M_TEMP);
343 	}
344 #endif
345 	*retval = cnt;
346 done:
347 	if (needfree)
348 		FREE(needfree, M_IOV);
349 	return (error);
350 }
351 
352 /*
353  * Ioctl system call
354  */
355 struct ioctl_args {
356 	int	fd;
357 	int	com;
358 	caddr_t	data;
359 };
360 /* ARGSUSED */
361 int
362 ioctl(p, uap, retval)
363 	struct proc *p;
364 	register struct ioctl_args *uap;
365 	int *retval;
366 {
367 	register struct file *fp;
368 	register struct filedesc *fdp;
369 	register int com, error;
370 	register u_int size;
371 	caddr_t data, memp;
372 	int tmp;
373 #define STK_PARAMS	128
374 	char stkbuf[STK_PARAMS];
375 
376 	fdp = p->p_fd;
377 	if ((u_int)uap->fd >= fdp->fd_nfiles ||
378 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
379 		return (EBADF);
380 
381 	if ((fp->f_flag & (FREAD | FWRITE)) == 0)
382 		return (EBADF);
383 
384 	switch (com = uap->com) {
385 	case FIONCLEX:
386 		fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE;
387 		return (0);
388 	case FIOCLEX:
389 		fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE;
390 		return (0);
391 	}
392 
393 	/*
394 	 * Interpret high order word to find amount of data to be
395 	 * copied to/from the user's address space.
396 	 */
397 	size = IOCPARM_LEN(com);
398 	if (size > IOCPARM_MAX)
399 		return (ENOTTY);
400 	memp = NULL;
401 	if (size > sizeof (stkbuf)) {
402 		memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
403 		data = memp;
404 	} else
405 		data = stkbuf;
406 	if (com&IOC_IN) {
407 		if (size) {
408 			error = copyin(uap->data, data, (u_int)size);
409 			if (error) {
410 				if (memp)
411 					free(memp, M_IOCTLOPS);
412 				return (error);
413 			}
414 		} else
415 			*(caddr_t *)data = uap->data;
416 	} else if ((com&IOC_OUT) && size)
417 		/*
418 		 * Zero the buffer so the user always
419 		 * gets back something deterministic.
420 		 */
421 		bzero(data, size);
422 	else if (com&IOC_VOID)
423 		*(caddr_t *)data = uap->data;
424 
425 	switch (com) {
426 
427 	case FIONBIO:
428 		if (tmp = *(int *)data)
429 			fp->f_flag |= FNONBLOCK;
430 		else
431 			fp->f_flag &= ~FNONBLOCK;
432 		error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
433 		break;
434 
435 	case FIOASYNC:
436 		if (tmp = *(int *)data)
437 			fp->f_flag |= FASYNC;
438 		else
439 			fp->f_flag &= ~FASYNC;
440 		error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
441 		break;
442 
443 	case FIOSETOWN:
444 		tmp = *(int *)data;
445 		if (fp->f_type == DTYPE_SOCKET) {
446 			((struct socket *)fp->f_data)->so_pgid = tmp;
447 			error = 0;
448 			break;
449 		}
450 		if (tmp <= 0) {
451 			tmp = -tmp;
452 		} else {
453 			struct proc *p1 = pfind(tmp);
454 			if (p1 == 0) {
455 				error = ESRCH;
456 				break;
457 			}
458 			tmp = p1->p_pgrp->pg_id;
459 		}
460 		error = (*fp->f_ops->fo_ioctl)
461 			(fp, (int)TIOCSPGRP, (caddr_t)&tmp, p);
462 		break;
463 
464 	case FIOGETOWN:
465 		if (fp->f_type == DTYPE_SOCKET) {
466 			error = 0;
467 			*(int *)data = ((struct socket *)fp->f_data)->so_pgid;
468 			break;
469 		}
470 		error = (*fp->f_ops->fo_ioctl)(fp, (int)TIOCGPGRP, data, p);
471 		*(int *)data = -*(int *)data;
472 		break;
473 
474 	default:
475 		error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
476 		/*
477 		 * Copy any data to user, size was
478 		 * already set and checked above.
479 		 */
480 		if (error == 0 && (com&IOC_OUT) && size)
481 			error = copyout(data, uap->data, (u_int)size);
482 		break;
483 	}
484 	if (memp)
485 		free(memp, M_IOCTLOPS);
486 	return (error);
487 }
488 
489 int	selwait, nselcoll;
490 
491 /*
492  * Select system call.
493  */
494 struct select_args {
495 	u_int	nd;
496 	fd_set	*in, *ou, *ex;
497 	struct	timeval *tv;
498 };
499 int
500 select(p, uap, retval)
501 	register struct proc *p;
502 	register struct select_args *uap;
503 	int *retval;
504 {
505 	fd_set ibits[3], obits[3];
506 	struct timeval atv;
507 	int s, ncoll, error = 0, timo;
508 	u_int ni;
509 
510 	bzero((caddr_t)ibits, sizeof(ibits));
511 	bzero((caddr_t)obits, sizeof(obits));
512 	if (uap->nd > FD_SETSIZE)
513 		return (EINVAL);
514 	if (uap->nd > p->p_fd->fd_nfiles)
515 		uap->nd = p->p_fd->fd_nfiles;	/* forgiving; slightly wrong */
516 	ni = howmany(uap->nd, NFDBITS) * sizeof(fd_mask);
517 
518 #define	getbits(name, x) \
519 	if (uap->name && \
520 	    (error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], ni))) \
521 		goto done;
522 	getbits(in, 0);
523 	getbits(ou, 1);
524 	getbits(ex, 2);
525 #undef	getbits
526 
527 	if (uap->tv) {
528 		error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
529 			sizeof (atv));
530 		if (error)
531 			goto done;
532 		if (itimerfix(&atv)) {
533 			error = EINVAL;
534 			goto done;
535 		}
536 		s = splclock();
537 		timevaladd(&atv, (struct timeval *)&time);
538 		timo = hzto(&atv);
539 		/*
540 		 * Avoid inadvertently sleeping forever.
541 		 */
542 		if (timo == 0)
543 			timo = 1;
544 		splx(s);
545 	} else
546 		timo = 0;
547 retry:
548 	ncoll = nselcoll;
549 	p->p_flag |= P_SELECT;
550 	error = selscan(p, ibits, obits, uap->nd, retval);
551 	if (error || *retval)
552 		goto done;
553 	s = splhigh();
554 	/* this should be timercmp(&time, &atv, >=) */
555 	if (uap->tv && (time.tv_sec > atv.tv_sec ||
556 	    time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec)) {
557 		splx(s);
558 		goto done;
559 	}
560 	if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
561 		splx(s);
562 		goto retry;
563 	}
564 	p->p_flag &= ~P_SELECT;
565 	error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
566 	splx(s);
567 	if (error == 0)
568 		goto retry;
569 done:
570 	p->p_flag &= ~P_SELECT;
571 	/* select is not restarted after signals... */
572 	if (error == ERESTART)
573 		error = EINTR;
574 	if (error == EWOULDBLOCK)
575 		error = 0;
576 #define	putbits(name, x) \
577 	if (uap->name && \
578 	    (error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, ni))) \
579 		error = error2;
580 	if (error == 0) {
581 		int error2;
582 
583 		putbits(in, 0);
584 		putbits(ou, 1);
585 		putbits(ex, 2);
586 #undef putbits
587 	}
588 	return (error);
589 }
590 
591 int
592 selscan(p, ibits, obits, nfd, retval)
593 	struct proc *p;
594 	fd_set *ibits, *obits;
595 	int nfd, *retval;
596 {
597 	register struct filedesc *fdp = p->p_fd;
598 	register int msk, i, j, fd;
599 	register fd_mask bits;
600 	struct file *fp;
601 	int n = 0;
602 	static int flag[3] = { FREAD, FWRITE, 0 };
603 
604 	for (msk = 0; msk < 3; msk++) {
605 		for (i = 0; i < nfd; i += NFDBITS) {
606 			bits = ibits[msk].fds_bits[i/NFDBITS];
607 			while ((j = ffs(bits)) && (fd = i + --j) < nfd) {
608 				bits &= ~(1 << j);
609 				fp = fdp->fd_ofiles[fd];
610 				if (fp == NULL)
611 					return (EBADF);
612 				if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
613 					FD_SET(fd, &obits[msk]);
614 					n++;
615 				}
616 			}
617 		}
618 	}
619 	*retval = n;
620 	return (0);
621 }
622 
623 /*ARGSUSED*/
624 int
625 seltrue(dev, flag, p)
626 	dev_t dev;
627 	int flag;
628 	struct proc *p;
629 {
630 
631 	return (1);
632 }
633 
634 /*
635  * Record a select request.
636  */
637 void
638 selrecord(selector, sip)
639 	struct proc *selector;
640 	struct selinfo *sip;
641 {
642 	struct proc *p;
643 	pid_t mypid;
644 
645 	mypid = selector->p_pid;
646 	if (sip->si_pid == mypid)
647 		return;
648 	if (sip->si_pid && (p = pfind(sip->si_pid)) &&
649 	    p->p_wchan == (caddr_t)&selwait)
650 		sip->si_flags |= SI_COLL;
651 	else
652 		sip->si_pid = mypid;
653 }
654 
655 /*
656  * Do a wakeup when a selectable event occurs.
657  */
658 void
659 selwakeup(sip)
660 	register struct selinfo *sip;
661 {
662 	register struct proc *p;
663 	int s;
664 
665 	if (sip->si_pid == 0)
666 		return;
667 	if (sip->si_flags & SI_COLL) {
668 		nselcoll++;
669 		sip->si_flags &= ~SI_COLL;
670 		wakeup((caddr_t)&selwait);
671 	}
672 	p = pfind(sip->si_pid);
673 	sip->si_pid = 0;
674 	if (p != NULL) {
675 		s = splhigh();
676 		if (p->p_wchan == (caddr_t)&selwait) {
677 			if (p->p_stat == SSLEEP)
678 				setrunnable(p);
679 			else
680 				unsleep(p);
681 		} else if (p->p_flag & P_SELECT)
682 			p->p_flag &= ~P_SELECT;
683 		splx(s);
684 	}
685 }
686