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
| 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
|
63 64/* 65 * Read system call. 66 */ 67#ifndef _SYS_SYSPROTO_H_ 68struct read_args { 69 int fd; 70 char *buf; 71 u_int nbyte; 72}; 73#endif 74/* ARGSUSED */ 75int 76read(p, uap, retval) 77 struct proc *p; 78 register struct read_args *uap; 79 int *retval; 80{ 81 register struct file *fp; 82 register struct filedesc *fdp = p->p_fd; 83 struct uio auio; 84 struct iovec aiov; 85 long cnt, error = 0; 86#ifdef KTRACE 87 struct iovec ktriov; 88#endif 89 90 if (((u_int)uap->fd) >= fdp->fd_nfiles || 91 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 92 (fp->f_flag & FREAD) == 0) 93 return (EBADF); 94 aiov.iov_base = (caddr_t)uap->buf; 95 aiov.iov_len = uap->nbyte; 96 auio.uio_iov = &aiov; 97 auio.uio_iovcnt = 1; 98 99 auio.uio_resid = uap->nbyte; 100 if (auio.uio_resid < 0) 101 return (EINVAL); 102 103 auio.uio_rw = UIO_READ; 104 auio.uio_segflg = UIO_USERSPACE; 105 auio.uio_procp = p; 106#ifdef KTRACE 107 /* 108 * if tracing, save a copy of iovec 109 */ 110 if (KTRPOINT(p, KTR_GENIO)) 111 ktriov = aiov; 112#endif 113 cnt = uap->nbyte; 114 if ((error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))) 115 if (auio.uio_resid != cnt && (error == ERESTART || 116 error == EINTR || error == EWOULDBLOCK)) 117 error = 0; 118 cnt -= auio.uio_resid; 119#ifdef KTRACE 120 if (KTRPOINT(p, KTR_GENIO) && error == 0) 121 ktrgenio(p->p_tracep, uap->fd, UIO_READ, &ktriov, cnt, error); 122#endif 123 *retval = cnt; 124 return (error); 125} 126 127/* 128 * Scatter read system call. 129 */ 130#ifndef _SYS_SYSPROTO_H_ 131struct readv_args { 132 int fd; 133 struct iovec *iovp; 134 u_int iovcnt; 135}; 136#endif 137int 138readv(p, uap, retval) 139 struct proc *p; 140 register struct readv_args *uap; 141 int *retval; 142{ 143 register struct file *fp; 144 register struct filedesc *fdp = p->p_fd; 145 struct uio auio; 146 register struct iovec *iov; 147 struct iovec *needfree; 148 struct iovec aiov[UIO_SMALLIOV]; 149 long i, cnt, error = 0; 150 u_int iovlen; 151#ifdef KTRACE 152 struct iovec *ktriov = NULL; 153#endif 154 155 if (((u_int)uap->fd) >= fdp->fd_nfiles || 156 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 157 (fp->f_flag & FREAD) == 0) 158 return (EBADF); 159 /* note: can't use iovlen until iovcnt is validated */ 160 iovlen = uap->iovcnt * sizeof (struct iovec); 161 if (uap->iovcnt > UIO_SMALLIOV) { 162 if (uap->iovcnt > UIO_MAXIOV) 163 return (EINVAL); 164 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 165 needfree = iov; 166 } else { 167 iov = aiov; 168 needfree = NULL; 169 } 170 auio.uio_iov = iov; 171 auio.uio_iovcnt = uap->iovcnt; 172 auio.uio_rw = UIO_READ; 173 auio.uio_segflg = UIO_USERSPACE; 174 auio.uio_procp = p; 175 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 176 goto done; 177 auio.uio_resid = 0; 178 for (i = 0; i < uap->iovcnt; i++) { 179 auio.uio_resid += iov->iov_len; 180 if (auio.uio_resid < 0) { 181 error = EINVAL; 182 goto done; 183 } 184 iov++; 185 } 186#ifdef KTRACE 187 /* 188 * if tracing, save a copy of iovec 189 */ 190 if (KTRPOINT(p, KTR_GENIO)) { 191 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 192 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 193 } 194#endif 195 cnt = auio.uio_resid; 196 if ((error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))) 197 if (auio.uio_resid != cnt && (error == ERESTART || 198 error == EINTR || error == EWOULDBLOCK)) 199 error = 0; 200 cnt -= auio.uio_resid; 201#ifdef KTRACE 202 if (ktriov != NULL) { 203 if (error == 0) 204 ktrgenio(p->p_tracep, uap->fd, UIO_READ, ktriov, 205 cnt, error); 206 FREE(ktriov, M_TEMP); 207 } 208#endif 209 *retval = cnt; 210done: 211 if (needfree) 212 FREE(needfree, M_IOV); 213 return (error); 214} 215 216/* 217 * Write system call 218 */ 219#ifndef _SYS_SYSPROTO_H_ 220struct write_args { 221 int fd; 222 char *buf; 223 u_int nbyte; 224}; 225#endif 226int 227write(p, uap, retval) 228 struct proc *p; 229 register struct write_args *uap; 230 int *retval; 231{ 232 register struct file *fp; 233 register struct filedesc *fdp = p->p_fd; 234 struct uio auio; 235 struct iovec aiov; 236 long cnt, error = 0; 237#ifdef KTRACE 238 struct iovec ktriov; 239#endif 240 241 if (((u_int)uap->fd) >= fdp->fd_nfiles || 242 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 243 (fp->f_flag & FWRITE) == 0) 244 return (EBADF); 245 aiov.iov_base = (caddr_t)uap->buf; 246 aiov.iov_len = uap->nbyte; 247 auio.uio_iov = &aiov; 248 auio.uio_iovcnt = 1; 249 auio.uio_resid = uap->nbyte; 250 auio.uio_rw = UIO_WRITE; 251 auio.uio_segflg = UIO_USERSPACE; 252 auio.uio_procp = p; 253#ifdef KTRACE 254 /* 255 * if tracing, save a copy of iovec 256 */ 257 if (KTRPOINT(p, KTR_GENIO)) 258 ktriov = aiov; 259#endif 260 cnt = uap->nbyte; 261 if ((error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred))) { 262 if (auio.uio_resid != cnt && (error == ERESTART || 263 error == EINTR || error == EWOULDBLOCK)) 264 error = 0; 265 if (error == EPIPE) 266 psignal(p, SIGPIPE); 267 } 268 cnt -= auio.uio_resid; 269#ifdef KTRACE 270 if (KTRPOINT(p, KTR_GENIO) && error == 0) 271 ktrgenio(p->p_tracep, uap->fd, UIO_WRITE, 272 &ktriov, cnt, error); 273#endif 274 *retval = cnt; 275 return (error); 276} 277 278/* 279 * Gather write system call 280 */ 281#ifndef _SYS_SYSPROTO_H_ 282struct writev_args { 283 int fd; 284 struct iovec *iovp; 285 u_int iovcnt; 286}; 287#endif 288int 289writev(p, uap, retval) 290 struct proc *p; 291 register struct writev_args *uap; 292 int *retval; 293{ 294 register struct file *fp; 295 register struct filedesc *fdp = p->p_fd; 296 struct uio auio; 297 register struct iovec *iov; 298 struct iovec *needfree; 299 struct iovec aiov[UIO_SMALLIOV]; 300 long i, cnt, error = 0; 301 u_int iovlen; 302#ifdef KTRACE 303 struct iovec *ktriov = NULL; 304#endif 305 306 if (((u_int)uap->fd) >= fdp->fd_nfiles || 307 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 308 (fp->f_flag & FWRITE) == 0) 309 return (EBADF); 310 /* note: can't use iovlen until iovcnt is validated */ 311 iovlen = uap->iovcnt * sizeof (struct iovec); 312 if (uap->iovcnt > UIO_SMALLIOV) { 313 if (uap->iovcnt > UIO_MAXIOV) 314 return (EINVAL); 315 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 316 needfree = iov; 317 } else { 318 iov = aiov; 319 needfree = NULL; 320 } 321 auio.uio_iov = iov; 322 auio.uio_iovcnt = uap->iovcnt; 323 auio.uio_rw = UIO_WRITE; 324 auio.uio_segflg = UIO_USERSPACE; 325 auio.uio_procp = p; 326 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 327 goto done; 328 auio.uio_resid = 0; 329 for (i = 0; i < uap->iovcnt; i++) { 330 auio.uio_resid += iov->iov_len; 331 if (auio.uio_resid < 0) { 332 error = EINVAL; 333 goto done; 334 } 335 iov++; 336 } 337#ifdef KTRACE 338 /* 339 * if tracing, save a copy of iovec 340 */ 341 if (KTRPOINT(p, KTR_GENIO)) { 342 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 343 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 344 } 345#endif 346 cnt = auio.uio_resid; 347 if ((error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred))) { 348 if (auio.uio_resid != cnt && (error == ERESTART || 349 error == EINTR || error == EWOULDBLOCK)) 350 error = 0; 351 if (error == EPIPE) 352 psignal(p, SIGPIPE); 353 } 354 cnt -= auio.uio_resid; 355#ifdef KTRACE 356 if (ktriov != NULL) { 357 if (error == 0) 358 ktrgenio(p->p_tracep, uap->fd, UIO_WRITE, 359 ktriov, cnt, error); 360 FREE(ktriov, M_TEMP); 361 } 362#endif 363 *retval = cnt; 364done: 365 if (needfree) 366 FREE(needfree, M_IOV); 367 return (error); 368} 369 370/* 371 * Ioctl system call 372 */ 373#ifndef _SYS_SYSPROTO_H_ 374struct ioctl_args { 375 int fd; 376 int com; 377 caddr_t data; 378}; 379#endif 380/* ARGSUSED */ 381int 382ioctl(p, uap, retval) 383 struct proc *p; 384 register struct ioctl_args *uap; 385 int *retval; 386{ 387 register struct file *fp; 388 register struct filedesc *fdp; 389 register int com, error; 390 register u_int size; 391 caddr_t data, memp; 392 int tmp; 393#define STK_PARAMS 128 394 char stkbuf[STK_PARAMS]; 395 396 fdp = p->p_fd; 397 if ((u_int)uap->fd >= fdp->fd_nfiles || 398 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 399 return (EBADF); 400 401 if ((fp->f_flag & (FREAD | FWRITE)) == 0) 402 return (EBADF); 403 404 switch (com = uap->com) { 405 case FIONCLEX: 406 fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE; 407 return (0); 408 case FIOCLEX: 409 fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE; 410 return (0); 411 } 412 413 /* 414 * Interpret high order word to find amount of data to be 415 * copied to/from the user's address space. 416 */ 417 size = IOCPARM_LEN(com); 418 if (size > IOCPARM_MAX) 419 return (ENOTTY); 420 memp = NULL; 421 if (size > sizeof (stkbuf)) { 422 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 423 data = memp; 424 } else 425 data = stkbuf; 426 if (com&IOC_IN) { 427 if (size) { 428 error = copyin(uap->data, data, (u_int)size); 429 if (error) { 430 if (memp) 431 free(memp, M_IOCTLOPS); 432 return (error); 433 } 434 } else 435 *(caddr_t *)data = uap->data; 436 } else if ((com&IOC_OUT) && size) 437 /* 438 * Zero the buffer so the user always 439 * gets back something deterministic. 440 */ 441 bzero(data, size); 442 else if (com&IOC_VOID) 443 *(caddr_t *)data = uap->data; 444 445 switch (com) { 446 447 case FIONBIO: 448 if ((tmp = *(int *)data)) 449 fp->f_flag |= FNONBLOCK; 450 else 451 fp->f_flag &= ~FNONBLOCK; 452 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p); 453 break; 454 455 case FIOASYNC: 456 if ((tmp = *(int *)data)) 457 fp->f_flag |= FASYNC; 458 else 459 fp->f_flag &= ~FASYNC; 460 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p); 461 break; 462 463 case FIOSETOWN: 464 tmp = *(int *)data; 465 if (fp->f_type == DTYPE_SOCKET) { 466 ((struct socket *)fp->f_data)->so_pgid = tmp; 467 error = 0; 468 break; 469 } 470 if (tmp <= 0) { 471 tmp = -tmp; 472 } else { 473 struct proc *p1 = pfind(tmp); 474 if (p1 == 0) { 475 error = ESRCH; 476 break; 477 } 478 tmp = p1->p_pgrp->pg_id; 479 } 480 error = (*fp->f_ops->fo_ioctl) 481 (fp, (int)TIOCSPGRP, (caddr_t)&tmp, p); 482 break; 483 484 case FIOGETOWN: 485 if (fp->f_type == DTYPE_SOCKET) { 486 error = 0; 487 *(int *)data = ((struct socket *)fp->f_data)->so_pgid; 488 break; 489 } 490 error = (*fp->f_ops->fo_ioctl)(fp, (int)TIOCGPGRP, data, p); 491 *(int *)data = -*(int *)data; 492 break; 493 494 default: 495 error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); 496 /* 497 * Copy any data to user, size was 498 * already set and checked above. 499 */ 500 if (error == 0 && (com&IOC_OUT) && size) 501 error = copyout(data, uap->data, (u_int)size); 502 break; 503 } 504 if (memp) 505 free(memp, M_IOCTLOPS); 506 return (error); 507} 508
| 63 64/* 65 * Read system call. 66 */ 67#ifndef _SYS_SYSPROTO_H_ 68struct read_args { 69 int fd; 70 char *buf; 71 u_int nbyte; 72}; 73#endif 74/* ARGSUSED */ 75int 76read(p, uap, retval) 77 struct proc *p; 78 register struct read_args *uap; 79 int *retval; 80{ 81 register struct file *fp; 82 register struct filedesc *fdp = p->p_fd; 83 struct uio auio; 84 struct iovec aiov; 85 long cnt, error = 0; 86#ifdef KTRACE 87 struct iovec ktriov; 88#endif 89 90 if (((u_int)uap->fd) >= fdp->fd_nfiles || 91 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 92 (fp->f_flag & FREAD) == 0) 93 return (EBADF); 94 aiov.iov_base = (caddr_t)uap->buf; 95 aiov.iov_len = uap->nbyte; 96 auio.uio_iov = &aiov; 97 auio.uio_iovcnt = 1; 98 99 auio.uio_resid = uap->nbyte; 100 if (auio.uio_resid < 0) 101 return (EINVAL); 102 103 auio.uio_rw = UIO_READ; 104 auio.uio_segflg = UIO_USERSPACE; 105 auio.uio_procp = p; 106#ifdef KTRACE 107 /* 108 * if tracing, save a copy of iovec 109 */ 110 if (KTRPOINT(p, KTR_GENIO)) 111 ktriov = aiov; 112#endif 113 cnt = uap->nbyte; 114 if ((error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))) 115 if (auio.uio_resid != cnt && (error == ERESTART || 116 error == EINTR || error == EWOULDBLOCK)) 117 error = 0; 118 cnt -= auio.uio_resid; 119#ifdef KTRACE 120 if (KTRPOINT(p, KTR_GENIO) && error == 0) 121 ktrgenio(p->p_tracep, uap->fd, UIO_READ, &ktriov, cnt, error); 122#endif 123 *retval = cnt; 124 return (error); 125} 126 127/* 128 * Scatter read system call. 129 */ 130#ifndef _SYS_SYSPROTO_H_ 131struct readv_args { 132 int fd; 133 struct iovec *iovp; 134 u_int iovcnt; 135}; 136#endif 137int 138readv(p, uap, retval) 139 struct proc *p; 140 register struct readv_args *uap; 141 int *retval; 142{ 143 register struct file *fp; 144 register struct filedesc *fdp = p->p_fd; 145 struct uio auio; 146 register struct iovec *iov; 147 struct iovec *needfree; 148 struct iovec aiov[UIO_SMALLIOV]; 149 long i, cnt, error = 0; 150 u_int iovlen; 151#ifdef KTRACE 152 struct iovec *ktriov = NULL; 153#endif 154 155 if (((u_int)uap->fd) >= fdp->fd_nfiles || 156 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 157 (fp->f_flag & FREAD) == 0) 158 return (EBADF); 159 /* note: can't use iovlen until iovcnt is validated */ 160 iovlen = uap->iovcnt * sizeof (struct iovec); 161 if (uap->iovcnt > UIO_SMALLIOV) { 162 if (uap->iovcnt > UIO_MAXIOV) 163 return (EINVAL); 164 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 165 needfree = iov; 166 } else { 167 iov = aiov; 168 needfree = NULL; 169 } 170 auio.uio_iov = iov; 171 auio.uio_iovcnt = uap->iovcnt; 172 auio.uio_rw = UIO_READ; 173 auio.uio_segflg = UIO_USERSPACE; 174 auio.uio_procp = p; 175 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 176 goto done; 177 auio.uio_resid = 0; 178 for (i = 0; i < uap->iovcnt; i++) { 179 auio.uio_resid += iov->iov_len; 180 if (auio.uio_resid < 0) { 181 error = EINVAL; 182 goto done; 183 } 184 iov++; 185 } 186#ifdef KTRACE 187 /* 188 * if tracing, save a copy of iovec 189 */ 190 if (KTRPOINT(p, KTR_GENIO)) { 191 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 192 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 193 } 194#endif 195 cnt = auio.uio_resid; 196 if ((error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))) 197 if (auio.uio_resid != cnt && (error == ERESTART || 198 error == EINTR || error == EWOULDBLOCK)) 199 error = 0; 200 cnt -= auio.uio_resid; 201#ifdef KTRACE 202 if (ktriov != NULL) { 203 if (error == 0) 204 ktrgenio(p->p_tracep, uap->fd, UIO_READ, ktriov, 205 cnt, error); 206 FREE(ktriov, M_TEMP); 207 } 208#endif 209 *retval = cnt; 210done: 211 if (needfree) 212 FREE(needfree, M_IOV); 213 return (error); 214} 215 216/* 217 * Write system call 218 */ 219#ifndef _SYS_SYSPROTO_H_ 220struct write_args { 221 int fd; 222 char *buf; 223 u_int nbyte; 224}; 225#endif 226int 227write(p, uap, retval) 228 struct proc *p; 229 register struct write_args *uap; 230 int *retval; 231{ 232 register struct file *fp; 233 register struct filedesc *fdp = p->p_fd; 234 struct uio auio; 235 struct iovec aiov; 236 long cnt, error = 0; 237#ifdef KTRACE 238 struct iovec ktriov; 239#endif 240 241 if (((u_int)uap->fd) >= fdp->fd_nfiles || 242 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 243 (fp->f_flag & FWRITE) == 0) 244 return (EBADF); 245 aiov.iov_base = (caddr_t)uap->buf; 246 aiov.iov_len = uap->nbyte; 247 auio.uio_iov = &aiov; 248 auio.uio_iovcnt = 1; 249 auio.uio_resid = uap->nbyte; 250 auio.uio_rw = UIO_WRITE; 251 auio.uio_segflg = UIO_USERSPACE; 252 auio.uio_procp = p; 253#ifdef KTRACE 254 /* 255 * if tracing, save a copy of iovec 256 */ 257 if (KTRPOINT(p, KTR_GENIO)) 258 ktriov = aiov; 259#endif 260 cnt = uap->nbyte; 261 if ((error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred))) { 262 if (auio.uio_resid != cnt && (error == ERESTART || 263 error == EINTR || error == EWOULDBLOCK)) 264 error = 0; 265 if (error == EPIPE) 266 psignal(p, SIGPIPE); 267 } 268 cnt -= auio.uio_resid; 269#ifdef KTRACE 270 if (KTRPOINT(p, KTR_GENIO) && error == 0) 271 ktrgenio(p->p_tracep, uap->fd, UIO_WRITE, 272 &ktriov, cnt, error); 273#endif 274 *retval = cnt; 275 return (error); 276} 277 278/* 279 * Gather write system call 280 */ 281#ifndef _SYS_SYSPROTO_H_ 282struct writev_args { 283 int fd; 284 struct iovec *iovp; 285 u_int iovcnt; 286}; 287#endif 288int 289writev(p, uap, retval) 290 struct proc *p; 291 register struct writev_args *uap; 292 int *retval; 293{ 294 register struct file *fp; 295 register struct filedesc *fdp = p->p_fd; 296 struct uio auio; 297 register struct iovec *iov; 298 struct iovec *needfree; 299 struct iovec aiov[UIO_SMALLIOV]; 300 long i, cnt, error = 0; 301 u_int iovlen; 302#ifdef KTRACE 303 struct iovec *ktriov = NULL; 304#endif 305 306 if (((u_int)uap->fd) >= fdp->fd_nfiles || 307 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 308 (fp->f_flag & FWRITE) == 0) 309 return (EBADF); 310 /* note: can't use iovlen until iovcnt is validated */ 311 iovlen = uap->iovcnt * sizeof (struct iovec); 312 if (uap->iovcnt > UIO_SMALLIOV) { 313 if (uap->iovcnt > UIO_MAXIOV) 314 return (EINVAL); 315 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 316 needfree = iov; 317 } else { 318 iov = aiov; 319 needfree = NULL; 320 } 321 auio.uio_iov = iov; 322 auio.uio_iovcnt = uap->iovcnt; 323 auio.uio_rw = UIO_WRITE; 324 auio.uio_segflg = UIO_USERSPACE; 325 auio.uio_procp = p; 326 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))) 327 goto done; 328 auio.uio_resid = 0; 329 for (i = 0; i < uap->iovcnt; i++) { 330 auio.uio_resid += iov->iov_len; 331 if (auio.uio_resid < 0) { 332 error = EINVAL; 333 goto done; 334 } 335 iov++; 336 } 337#ifdef KTRACE 338 /* 339 * if tracing, save a copy of iovec 340 */ 341 if (KTRPOINT(p, KTR_GENIO)) { 342 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 343 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 344 } 345#endif 346 cnt = auio.uio_resid; 347 if ((error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred))) { 348 if (auio.uio_resid != cnt && (error == ERESTART || 349 error == EINTR || error == EWOULDBLOCK)) 350 error = 0; 351 if (error == EPIPE) 352 psignal(p, SIGPIPE); 353 } 354 cnt -= auio.uio_resid; 355#ifdef KTRACE 356 if (ktriov != NULL) { 357 if (error == 0) 358 ktrgenio(p->p_tracep, uap->fd, UIO_WRITE, 359 ktriov, cnt, error); 360 FREE(ktriov, M_TEMP); 361 } 362#endif 363 *retval = cnt; 364done: 365 if (needfree) 366 FREE(needfree, M_IOV); 367 return (error); 368} 369 370/* 371 * Ioctl system call 372 */ 373#ifndef _SYS_SYSPROTO_H_ 374struct ioctl_args { 375 int fd; 376 int com; 377 caddr_t data; 378}; 379#endif 380/* ARGSUSED */ 381int 382ioctl(p, uap, retval) 383 struct proc *p; 384 register struct ioctl_args *uap; 385 int *retval; 386{ 387 register struct file *fp; 388 register struct filedesc *fdp; 389 register int com, error; 390 register u_int size; 391 caddr_t data, memp; 392 int tmp; 393#define STK_PARAMS 128 394 char stkbuf[STK_PARAMS]; 395 396 fdp = p->p_fd; 397 if ((u_int)uap->fd >= fdp->fd_nfiles || 398 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 399 return (EBADF); 400 401 if ((fp->f_flag & (FREAD | FWRITE)) == 0) 402 return (EBADF); 403 404 switch (com = uap->com) { 405 case FIONCLEX: 406 fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE; 407 return (0); 408 case FIOCLEX: 409 fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE; 410 return (0); 411 } 412 413 /* 414 * Interpret high order word to find amount of data to be 415 * copied to/from the user's address space. 416 */ 417 size = IOCPARM_LEN(com); 418 if (size > IOCPARM_MAX) 419 return (ENOTTY); 420 memp = NULL; 421 if (size > sizeof (stkbuf)) { 422 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 423 data = memp; 424 } else 425 data = stkbuf; 426 if (com&IOC_IN) { 427 if (size) { 428 error = copyin(uap->data, data, (u_int)size); 429 if (error) { 430 if (memp) 431 free(memp, M_IOCTLOPS); 432 return (error); 433 } 434 } else 435 *(caddr_t *)data = uap->data; 436 } else if ((com&IOC_OUT) && size) 437 /* 438 * Zero the buffer so the user always 439 * gets back something deterministic. 440 */ 441 bzero(data, size); 442 else if (com&IOC_VOID) 443 *(caddr_t *)data = uap->data; 444 445 switch (com) { 446 447 case FIONBIO: 448 if ((tmp = *(int *)data)) 449 fp->f_flag |= FNONBLOCK; 450 else 451 fp->f_flag &= ~FNONBLOCK; 452 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p); 453 break; 454 455 case FIOASYNC: 456 if ((tmp = *(int *)data)) 457 fp->f_flag |= FASYNC; 458 else 459 fp->f_flag &= ~FASYNC; 460 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p); 461 break; 462 463 case FIOSETOWN: 464 tmp = *(int *)data; 465 if (fp->f_type == DTYPE_SOCKET) { 466 ((struct socket *)fp->f_data)->so_pgid = tmp; 467 error = 0; 468 break; 469 } 470 if (tmp <= 0) { 471 tmp = -tmp; 472 } else { 473 struct proc *p1 = pfind(tmp); 474 if (p1 == 0) { 475 error = ESRCH; 476 break; 477 } 478 tmp = p1->p_pgrp->pg_id; 479 } 480 error = (*fp->f_ops->fo_ioctl) 481 (fp, (int)TIOCSPGRP, (caddr_t)&tmp, p); 482 break; 483 484 case FIOGETOWN: 485 if (fp->f_type == DTYPE_SOCKET) { 486 error = 0; 487 *(int *)data = ((struct socket *)fp->f_data)->so_pgid; 488 break; 489 } 490 error = (*fp->f_ops->fo_ioctl)(fp, (int)TIOCGPGRP, data, p); 491 *(int *)data = -*(int *)data; 492 break; 493 494 default: 495 error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); 496 /* 497 * Copy any data to user, size was 498 * already set and checked above. 499 */ 500 if (error == 0 && (com&IOC_OUT) && size) 501 error = copyout(data, uap->data, (u_int)size); 502 break; 503 } 504 if (memp) 505 free(memp, M_IOCTLOPS); 506 return (error); 507} 508
|
510 511/* 512 * Select system call. 513 */ 514#ifndef _SYS_SYSPROTO_H_ 515struct select_args { 516 u_int nd; 517 fd_set *in, *ou, *ex; 518 struct timeval *tv; 519}; 520#endif 521int 522select(p, uap, retval) 523 register struct proc *p; 524 register struct select_args *uap; 525 int *retval; 526{ 527 fd_set ibits[3], obits[3]; 528 struct timeval atv; 529 int s, ncoll, error = 0, timo; 530 u_int ni; 531 532 bzero((caddr_t)ibits, sizeof(ibits)); 533 bzero((caddr_t)obits, sizeof(obits)); 534 if (uap->nd > FD_SETSIZE) 535 return (EINVAL); 536 if (uap->nd > p->p_fd->fd_nfiles) 537 uap->nd = p->p_fd->fd_nfiles; /* forgiving; slightly wrong */ 538 ni = howmany(uap->nd, NFDBITS) * sizeof(fd_mask); 539 540#define getbits(name, x) \ 541 if (uap->name && \ 542 (error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], ni))) \ 543 goto done; 544 getbits(in, 0); 545 getbits(ou, 1); 546 getbits(ex, 2); 547#undef getbits 548 549 if (uap->tv) { 550 error = copyin((caddr_t)uap->tv, (caddr_t)&atv, 551 sizeof (atv)); 552 if (error) 553 goto done; 554 if (itimerfix(&atv)) { 555 error = EINVAL; 556 goto done; 557 } 558 s = splclock(); 559 timevaladd(&atv, (struct timeval *)&time); 560 timo = hzto(&atv); 561 /* 562 * Avoid inadvertently sleeping forever. 563 */ 564 if (timo == 0) 565 timo = 1; 566 splx(s); 567 } else 568 timo = 0; 569retry: 570 ncoll = nselcoll; 571 p->p_flag |= P_SELECT; 572 error = selscan(p, ibits, obits, uap->nd, retval); 573 if (error || *retval) 574 goto done; 575 s = splhigh(); 576 /* this should be timercmp(&time, &atv, >=) */ 577 if (uap->tv && (time.tv_sec > atv.tv_sec || 578 (time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec))) { 579 splx(s); 580 goto done; 581 } 582 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { 583 splx(s); 584 goto retry; 585 } 586 p->p_flag &= ~P_SELECT; 587 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 588 splx(s); 589 if (error == 0) 590 goto retry; 591done: 592 p->p_flag &= ~P_SELECT; 593 /* select is not restarted after signals... */ 594 if (error == ERESTART) 595 error = EINTR; 596 if (error == EWOULDBLOCK) 597 error = 0; 598#define putbits(name, x) \ 599 if (uap->name && \ 600 (error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, ni))) \ 601 error = error2; 602 if (error == 0) { 603 int error2; 604 605 putbits(in, 0); 606 putbits(ou, 1); 607 putbits(ex, 2); 608#undef putbits 609 } 610 return (error); 611} 612
| 511 512/* 513 * Select system call. 514 */ 515#ifndef _SYS_SYSPROTO_H_ 516struct select_args { 517 u_int nd; 518 fd_set *in, *ou, *ex; 519 struct timeval *tv; 520}; 521#endif 522int 523select(p, uap, retval) 524 register struct proc *p; 525 register struct select_args *uap; 526 int *retval; 527{ 528 fd_set ibits[3], obits[3]; 529 struct timeval atv; 530 int s, ncoll, error = 0, timo; 531 u_int ni; 532 533 bzero((caddr_t)ibits, sizeof(ibits)); 534 bzero((caddr_t)obits, sizeof(obits)); 535 if (uap->nd > FD_SETSIZE) 536 return (EINVAL); 537 if (uap->nd > p->p_fd->fd_nfiles) 538 uap->nd = p->p_fd->fd_nfiles; /* forgiving; slightly wrong */ 539 ni = howmany(uap->nd, NFDBITS) * sizeof(fd_mask); 540 541#define getbits(name, x) \ 542 if (uap->name && \ 543 (error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], ni))) \ 544 goto done; 545 getbits(in, 0); 546 getbits(ou, 1); 547 getbits(ex, 2); 548#undef getbits 549 550 if (uap->tv) { 551 error = copyin((caddr_t)uap->tv, (caddr_t)&atv, 552 sizeof (atv)); 553 if (error) 554 goto done; 555 if (itimerfix(&atv)) { 556 error = EINVAL; 557 goto done; 558 } 559 s = splclock(); 560 timevaladd(&atv, (struct timeval *)&time); 561 timo = hzto(&atv); 562 /* 563 * Avoid inadvertently sleeping forever. 564 */ 565 if (timo == 0) 566 timo = 1; 567 splx(s); 568 } else 569 timo = 0; 570retry: 571 ncoll = nselcoll; 572 p->p_flag |= P_SELECT; 573 error = selscan(p, ibits, obits, uap->nd, retval); 574 if (error || *retval) 575 goto done; 576 s = splhigh(); 577 /* this should be timercmp(&time, &atv, >=) */ 578 if (uap->tv && (time.tv_sec > atv.tv_sec || 579 (time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec))) { 580 splx(s); 581 goto done; 582 } 583 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { 584 splx(s); 585 goto retry; 586 } 587 p->p_flag &= ~P_SELECT; 588 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 589 splx(s); 590 if (error == 0) 591 goto retry; 592done: 593 p->p_flag &= ~P_SELECT; 594 /* select is not restarted after signals... */ 595 if (error == ERESTART) 596 error = EINTR; 597 if (error == EWOULDBLOCK) 598 error = 0; 599#define putbits(name, x) \ 600 if (uap->name && \ 601 (error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, ni))) \ 602 error = error2; 603 if (error == 0) { 604 int error2; 605 606 putbits(in, 0); 607 putbits(ou, 1); 608 putbits(ex, 2); 609#undef putbits 610 } 611 return (error); 612} 613
|