/* sys_generic.c 5.25 82/12/09 */
#include "../h/socketvar.h"
#include "../h/descrip.h"
} *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
<= 0 || uap
->iovcnt
> sizeof(aiov
)/sizeof(aiov
[0])) {
auio
.uio_iovcnt
= uap
->iovcnt
;
if (copyin((caddr_t
)uap
->iovp
, (caddr_t
)aiov
,
(unsigned)(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
<= 0 || uap
->iovcnt
> sizeof(aiov
)/sizeof(aiov
[0])) {
auio
.uio_iovcnt
= uap
->iovcnt
;
if (copyin((caddr_t
)uap
->iovp
, (caddr_t
)aiov
,
(unsigned)(uap
->iovcnt
* sizeof (struct iovec
)))) {
register struct uio
*uio
;
register struct file
*fp
;
register struct iovec
*iov
;
register struct inode
*ip
;
GETF(fp
, ((struct a
*)u
.u_ap
)->fdes
);
if ((fp
->f_flag
&(rw
==UIO_READ
? FREAD
: FWRITE
)) == 0) {
for (i
= 0; i
< uio
->uio_iovcnt
; i
++) {
uio
->uio_resid
+= iov
->iov_len
;
if (uio
->uio_resid
< 0) {
if ((u
.u_procp
->p_flag
&SNUSIG
) && setjmp(&u
.u_qsave
)) {
if (uio
->uio_resid
== count
)
} else if (fp
->f_type
== DTYPE_SOCKET
) {
int sosend(), soreceive();
(*(rw
==UIO_READ
?soreceive
:sosend
))
(fp
->f_socket
, (struct sockaddr
*)0, uio
, 0);
uio
->uio_offset
= fp
->f_offset
;
if ((ip
->i_mode
&IFMT
) == IFREG
) {
u
.u_error
= rwip(ip
, uio
, rw
);
u
.u_error
= rwip(ip
, uio
, rw
);
fp
->f_offset
+= count
- uio
->uio_resid
;
u
.u_r
.r_val1
= count
- uio
->uio_resid
;
rdwri(rw
, ip
, base
, len
, offset
, segflg
, aresid
)
auio
.uio_offset
= offset
;
auio
.uio_segflg
= segflg
;
error
= rwip(ip
, &auio
, rw
);
*aresid
= auio
.uio_resid
;
register struct inode
*ip
;
register struct uio
*uio
;
dev_t dev
= (dev_t
)ip
->i_rdev
;
register int n
, on
, type
;
if (rw
!= UIO_READ
&& rw
!= UIO_WRITE
)
if (rw
== UIO_READ
&& uio
->uio_resid
== 0)
if (uio
->uio_offset
< 0 &&
((ip
->i_mode
&IFMT
) != IFCHR
|| mem_no
!= major(dev
)))
register c
= uio
->uio_resid
;
u
.u_error
= (*cdevsw
[major(dev
)].d_read
)(dev
, uio
);
u
.u_error
= (*cdevsw
[major(dev
)].d_write
)(dev
, uio
);
CHARGE(sc_tio
* (c
- uio
->uio_resid
));
if (rw
== UIO_WRITE
&& type
== IFREG
&&
uio
->uio_offset
+ uio
->uio_resid
>
u
.u_rlimit
[RLIMIT_FSIZE
].rlim_cur
) {
psignal(u
.u_procp
, SIGXFSZ
);
lbn
= uio
->uio_offset
/ bsize
;
on
= uio
->uio_offset
% bsize
;
n
= MIN((unsigned)(bsize
- on
), uio
->uio_resid
);
int diff
= ip
->i_size
- uio
->uio_offset
;
bmap(ip
, lbn
, rw
== UIO_WRITE
? B_WRITE
: B_READ
, (int)(on
+n
)));
if (u
.u_error
|| rw
== UIO_WRITE
&& (long)bn
<0)
if (rw
== UIO_WRITE
&& uio
->uio_offset
+ n
> ip
->i_size
&&
(type
== IFDIR
|| type
== IFREG
|| type
== IFLNK
))
ip
->i_size
= uio
->uio_offset
+ n
;
size
= blksize(fs
, ip
, lbn
);
bn
= lbn
* (BLKDEV_IOSIZE
/DEV_BSIZE
);
rablock
= bn
+ (BLKDEV_IOSIZE
/DEV_BSIZE
);
} else if (ip
->i_lastr
+ 1 == lbn
)
bp
= breada(dev
, bn
, size
, rablock
, rasize
);
bp
= bread(dev
, bn
, size
);
extern struct cmap
*mfind();
count
= howmany(size
, DEV_BSIZE
);
for (i
= 0; i
< count
; i
+= CLSIZE
)
bp
= getblk(dev
, bn
, size
);
bp
= bread(dev
, bn
, size
);
n
= MIN(n
, size
- bp
->b_resid
);
if (bp
->b_flags
& B_ERROR
) {
uiomove(bp
->b_un
.b_addr
+on
, n
, rw
, uio
);
if (n
+ on
== bsize
|| uio
->uio_offset
== ip
->i_size
)
if ((ip
->i_mode
&IFMT
) == IFDIR
)
else if (n
+ on
== bsize
) {
ip
->i_mode
&= ~(ISUID
|ISGID
);
} while (u
.u_error
== 0 && uio
->uio_resid
> 0 && n
!= 0);
register struct uio
*uio
;
register struct iovec
*iov
;
while (n
> 0 && uio
->uio_resid
) {
switch (uio
->uio_segflg
) {
error
= copyout(cp
, iov
->iov_base
, cnt
);
error
= copyin(iov
->iov_base
, cp
, cnt
);
bcopy((caddr_t
)cp
, iov
->iov_base
, cnt
);
bcopy(iov
->iov_base
, (caddr_t
)cp
, cnt
);
* Give next character to user as result of read.
register struct uio
*uio
;
register struct iovec
*iov
;
if (uio
->uio_iovcnt
== 0)
if (iov
->iov_len
<= 0 || uio
->uio_resid
<= 0) {
switch (uio
->uio_segflg
) {
if (subyte(iov
->iov_base
, c
) < 0)
if (suibyte(iov
->iov_base
, c
) < 0)
* Get next character written in by user from uio.
register struct iovec
*iov
;
if (uio
->uio_iovcnt
<= 0 || uio
->uio_resid
<= 0)
switch (uio
->uio_segflg
) {
c
= fubyte(iov
->iov_base
);
c
= *iov
->iov_base
& 0377;
c
= fuibyte(iov
->iov_base
);
* Check legality, execute common code,
* and switch out to individual device routine.
register struct file
*fp
;
char data
[IOCPARM_MASK
+1];
uap
= (struct a
*)u
.u_ap
;
if ((fp
= getf(uap
->fdes
)) == NULL
)
if ((fp
->f_flag
& (FREAD
|FWRITE
)) == 0) {
* 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
size
= (com
&~ (IOC_INOUT
|IOC_VOID
)) >> 16;
if (size
> sizeof (data
)) {
if (com
&IOC_IN
&& size
) {
if (copyin(uap
->cmarg
, (caddr_t
)data
, (u_int
)size
)) {
*(caddr_t
*)data
= uap
->cmarg
;
* Zero the buffer on the stack so the user
* always gets back something deterministic.
if ((com
&IOC_OUT
) && size
)
bzero((caddr_t
)data
, size
);
if (fp
->f_type
== DTYPE_SOCKET
)
u
.u_error
= soioctl(fp
->f_socket
, com
, data
);
register struct inode
*ip
= fp
->f_inode
;
int fmt
= ip
->i_mode
& IFMT
;
if (com
== FIONREAD
&& (fmt
== IFREG
|| fmt
== IFDIR
)) {
*(off_t
*)data
= ip
->i_size
- fp
->f_offset
;
if (com
!= FIONBIO
&& com
!= FIOASYNC
)
if ((u
.u_procp
->p_flag
&SNUSIG
) && setjmp(&u
.u_qsave
)) {
u
.u_error
= (*cdevsw
[major(dev
)].d_ioctl
)(dev
, com
, data
, 0);
* Copy any data to user, size was
* already set and checked above.
if (u
.u_error
== 0 && (com
&IOC_OUT
))
if (size
&& copyout(data
, uap
->cmarg
, (u_int
)size
))
* Do nothing specific version of line
* discipline specific ioctl command.
nullioctl(tp
, cmd
, data
, flags
)
tp
= tp
; data
= data
; flags
= flags
;