* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)sys_generic.c 7.6 (Berkeley) %G%
} *uap
= (struct a
*)u
.u_ap
;
aiov
.iov_base
= (caddr_t
)uap
->cbuf
;
aiov
.iov_len
= uap
->count
;
} *uap
= (struct a
*)u
.u_ap
;
struct iovec aiov
[16]; /* XXX */
if (uap
->iovcnt
> sizeof(aiov
)/sizeof(aiov
[0])) {
auio
.uio_iovcnt
= uap
->iovcnt
;
u
.u_error
= copyin((caddr_t
)uap
->iovp
, (caddr_t
)aiov
,
uap
->iovcnt
* sizeof (struct iovec
));
} *uap
= (struct a
*)u
.u_ap
;
aiov
.iov_base
= uap
->cbuf
;
aiov
.iov_len
= uap
->count
;
} *uap
= (struct a
*)u
.u_ap
;
struct iovec aiov
[16]; /* XXX */
if (uap
->iovcnt
> sizeof(aiov
)/sizeof(aiov
[0])) {
auio
.uio_iovcnt
= uap
->iovcnt
;
u
.u_error
= copyin((caddr_t
)uap
->iovp
, (caddr_t
)aiov
,
uap
->iovcnt
* sizeof (struct iovec
));
register struct uio
*uio
;
register struct file
*fp
;
register struct iovec
*iov
;
GETF(fp
, ((struct a
*)u
.u_ap
)->fdes
);
if ((fp
->f_flag
&(rw
==UIO_READ
? FREAD
: FWRITE
)) == 0) {
uio
->uio_segflg
= UIO_USERSPACE
;
for (i
= 0; i
< uio
->uio_iovcnt
; i
++) {
uio
->uio_resid
+= iov
->iov_len
;
if (uio
->uio_resid
< 0) {
if (setjmp(&u
.u_qsave
)) {
if (uio
->uio_resid
== count
) {
if ((u
.u_sigintr
& sigmask(u
.u_procp
->p_cursig
)) != 0)
u
.u_error
= (*fp
->f_ops
->fo_rw
)(fp
, rw
, uio
);
u
.u_r
.r_val1
= count
- uio
->uio_resid
;
register struct file
*fp
;
uap
= (struct a
*)u
.u_ap
;
if ((fp
->f_flag
& (FREAD
|FWRITE
)) == 0) {
#if defined(vax) && defined(COMPAT)
* Map old style ioctl's into new for the
* sake of backwards compatibility (sigh).
if ((com
&~0xffff) == 0) {
u
.u_pofile
[uap
->fdes
] |= UF_EXCLOSE
;
u
.u_pofile
[uap
->fdes
] &= ~UF_EXCLOSE
;
* Interpret high order word to find
* amount of data to be copied to/from the
if (size
> IOCPARM_MAX
) {
if (size
> sizeof (stkbuf
)) {
memp
= (caddr_t
)malloc(IOCPARM_MAX
, M_IOCTLOPS
, M_WAITOK
);
copyin(uap
->cmarg
, data
, (u_int
)size
);
*(caddr_t
*)data
= uap
->cmarg
;
} else if ((com
&IOC_OUT
) && size
)
* Zero the buffer on the stack so the user
* always gets back something deterministic.
*(caddr_t
*)data
= uap
->cmarg
;
u
.u_error
= fset(fp
, FNDELAY
, *(int *)data
);
u
.u_error
= fset(fp
, FASYNC
, *(int *)data
);
u
.u_error
= fsetown(fp
, *(int *)data
);
u
.u_error
= fgetown(fp
, (int *)data
);
u
.u_error
= (*fp
->f_ops
->fo_ioctl
)(fp
, com
, data
);
* Copy any data to user, size was
* already set and checked above.
if (u
.u_error
== 0 && (com
&IOC_OUT
) && size
)
u
.u_error
= copyout(data
, uap
->cmarg
, (u_int
)size
);
} *uap
= (struct uap
*)u
.u_ap
;
fd_set ibits
[3], obits
[3];
bzero((caddr_t
)ibits
, sizeof(ibits
));
bzero((caddr_t
)obits
, sizeof(obits
));
uap
->nd
= NOFILE
; /* forgiving, if slightly wrong */
ni
= howmany(uap
->nd
, NFDBITS
);
#define getbits(name, x) \
u.u_error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \
(unsigned)(ni * sizeof(fd_mask))); \
u
.u_error
= copyin((caddr_t
)uap
->tv
, (caddr_t
)&atv
,
s
= splhigh(); timevaladd(&atv
, &time
); splx(s
);
u
.u_procp
->p_flag
|= SSEL
;
u
.u_r
.r_val1
= selscan(ibits
, obits
, uap
->nd
);
if (u
.u_error
|| u
.u_r
.r_val1
)
/* this should be timercmp(&time, &atv, >=) */
if (uap
->tv
&& (time
.tv_sec
> atv
.tv_sec
||
time
.tv_sec
== atv
.tv_sec
&& time
.tv_usec
>= atv
.tv_usec
)) {
if ((u
.u_procp
->p_flag
& SSEL
) == 0 || nselcoll
!= ncoll
) {
u
.u_procp
->p_flag
&= ~SSEL
;
if (setjmp(&u
.u_qsave
)) {
untimeout(unselect
, (caddr_t
)u
.u_procp
);
timeout(unselect
, (caddr_t
)u
.u_procp
, hzto(&atv
));
sleep((caddr_t
)&selwait
, PZERO
+1);
untimeout(unselect
, (caddr_t
)u
.u_procp
);
u
.u_procp
->p_flag
&= ~SSEL
;
#define putbits(name, x) \
int error = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \
(unsigned)(ni * sizeof(fd_mask))); \
register int s
= splhigh();
selscan(ibits
, obits
, nfd
)
register int which
, i
, j
;
for (which
= 0; which
< 3; which
++) {
for (i
= 0; i
< nfd
; i
+= NFDBITS
) {
bits
= ibits
[which
].fds_bits
[i
/NFDBITS
];
while ((j
= ffs(bits
)) && i
+ --j
< nfd
) {
if ((*fp
->f_ops
->fo_select
)(fp
, flag
)) {
FD_SET(i
+ j
, &obits
[which
]);
wakeup((caddr_t
)&selwait
);
if (p
->p_wchan
== (caddr_t
)&selwait
) {
} else if (p
->p_flag
& SSEL
)