* Extract the file pointer associated with the specified descriptor for the * current user process. * * If the descriptor doesn't exist or doesn't match 'flags', EBADF is * returned. * * File's rights will be checked against the capability rights mask. * * If an error occurred the non-zero error is returned and *fpp is set to * NULL. Otherwise *fpp is held and set and zero is returned.
| 3350 | * responsible for fdrop(). |
| 3351 | */ |
| 3352 | static __inline int |
| 3353 | _fget(struct thread *td, int fd, struct file **fpp, int flags, |
| 3354 | cap_rights_t *needrightsp) |
| 3355 | { |
| 3356 | struct filedesc *fdp; |
| 3357 | struct file *fp; |
| 3358 | int error; |
| 3359 | |
| 3360 | *fpp = NULL; |
| 3361 | fdp = td->td_proc->p_fd; |
| 3362 | error = fget_unlocked(fdp, fd, needrightsp, &fp); |
| 3363 | if (__predict_false(error != 0)) |
| 3364 | return (error); |
| 3365 | if (__predict_false(fp->f_ops == &badfileops)) { |
| 3366 | fdrop(fp, td); |
| 3367 | return (EBADF); |
| 3368 | } |
| 3369 | |
| 3370 | /* |
| 3371 | * FREAD and FWRITE failure return EBADF as per POSIX. |
| 3372 | */ |
| 3373 | error = 0; |
| 3374 | switch (flags) { |
| 3375 | case FREAD: |
| 3376 | case FWRITE: |
| 3377 | if ((fp->f_flag & flags) == 0) |
| 3378 | error = EBADF; |
| 3379 | break; |
| 3380 | case FEXEC: |
| 3381 | if ((fp->f_flag & (FREAD | FEXEC)) == 0 || |
| 3382 | ((fp->f_flag & FWRITE) != 0)) |
| 3383 | error = EBADF; |
| 3384 | break; |
| 3385 | case 0: |
| 3386 | break; |
| 3387 | default: |
| 3388 | KASSERT(0, ("wrong flags")); |
| 3389 | } |
| 3390 | |
| 3391 | if (error != 0) { |
| 3392 | fdrop(fp, td); |
| 3393 | return (error); |
| 3394 | } |
| 3395 | |
| 3396 | *fpp = fp; |
| 3397 | return (0); |
| 3398 | } |
| 3399 | |
| 3400 | int |
| 3401 | fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp) |
no test coverage detected