| 3328 | } |
| 3329 | |
| 3330 | int |
| 3331 | kern_utimensat(struct thread *td, int fd, const char *path, |
| 3332 | enum uio_seg pathseg, struct timespec *tptr, enum uio_seg tptrseg, |
| 3333 | int flag) |
| 3334 | { |
| 3335 | struct nameidata nd; |
| 3336 | struct timespec ts[2]; |
| 3337 | int error, flags; |
| 3338 | |
| 3339 | if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH)) != 0) |
| 3340 | return (EINVAL); |
| 3341 | |
| 3342 | if ((error = getutimens(tptr, tptrseg, ts, &flags)) != 0) |
| 3343 | return (error); |
| 3344 | NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW | |
| 3345 | AT_RESOLVE_BENEATH) | AUDITVNODE1, |
| 3346 | pathseg, path, fd, &cap_futimes_rights, td); |
| 3347 | if ((error = namei(&nd)) != 0) |
| 3348 | return (error); |
| 3349 | /* |
| 3350 | * We are allowed to call namei() regardless of 2xUTIME_OMIT. |
| 3351 | * POSIX states: |
| 3352 | * "If both tv_nsec fields are UTIME_OMIT... EACCESS may be detected." |
| 3353 | * "Search permission is denied by a component of the path prefix." |
| 3354 | */ |
| 3355 | NDFREE_NOTHING(&nd); |
| 3356 | if ((flags & UTIMENS_EXIT) == 0) |
| 3357 | error = setutimes(td, nd.ni_vp, ts, 2, flags & UTIMENS_NULL); |
| 3358 | vrele(nd.ni_vp); |
| 3359 | return (error); |
| 3360 | } |
| 3361 | |
| 3362 | /* |
| 3363 | * Truncate a file given its path name. |
no test coverage detected