* If the core format has a %I in it, then we need to check * for existing corefiles before defining a name. * To do this we iterate over 0..ncores to find a * non-existing core file name to use. If all core files are * already used we choose the oldest one. */
| 3501 | * already used we choose the oldest one. |
| 3502 | */ |
| 3503 | static int |
| 3504 | corefile_open_last(struct thread *td, char *name, int indexpos, |
| 3505 | int indexlen, int ncores, struct vnode **vpp) |
| 3506 | { |
| 3507 | struct vnode *oldvp, *nextvp, *vp; |
| 3508 | struct vattr vattr; |
| 3509 | struct nameidata nd; |
| 3510 | int error, i, flags, oflags, cmode; |
| 3511 | char ch; |
| 3512 | struct timespec lasttime; |
| 3513 | |
| 3514 | nextvp = oldvp = NULL; |
| 3515 | cmode = S_IRUSR | S_IWUSR; |
| 3516 | oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE | |
| 3517 | (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0); |
| 3518 | |
| 3519 | for (i = 0; i < ncores; i++) { |
| 3520 | flags = O_CREAT | FWRITE | O_NOFOLLOW; |
| 3521 | |
| 3522 | ch = name[indexpos + indexlen]; |
| 3523 | (void)snprintf(name + indexpos, indexlen + 1, "%.*u", indexlen, |
| 3524 | i); |
| 3525 | name[indexpos + indexlen] = ch; |
| 3526 | |
| 3527 | NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td); |
| 3528 | error = vn_open_cred(&nd, &flags, cmode, oflags, td->td_ucred, |
| 3529 | NULL); |
| 3530 | if (error != 0) |
| 3531 | break; |
| 3532 | |
| 3533 | vp = nd.ni_vp; |
| 3534 | NDFREE(&nd, NDF_ONLY_PNBUF); |
| 3535 | if ((flags & O_CREAT) == O_CREAT) { |
| 3536 | nextvp = vp; |
| 3537 | break; |
| 3538 | } |
| 3539 | |
| 3540 | error = VOP_GETATTR(vp, &vattr, td->td_ucred); |
| 3541 | if (error != 0) { |
| 3542 | vnode_close_locked(td, vp); |
| 3543 | break; |
| 3544 | } |
| 3545 | |
| 3546 | if (oldvp == NULL || |
| 3547 | lasttime.tv_sec > vattr.va_mtime.tv_sec || |
| 3548 | (lasttime.tv_sec == vattr.va_mtime.tv_sec && |
| 3549 | lasttime.tv_nsec >= vattr.va_mtime.tv_nsec)) { |
| 3550 | if (oldvp != NULL) |
| 3551 | vn_close(oldvp, FWRITE, td->td_ucred, td); |
| 3552 | oldvp = vp; |
| 3553 | VOP_UNLOCK(oldvp); |
| 3554 | lasttime = vattr.va_mtime; |
| 3555 | } else { |
| 3556 | vnode_close_locked(td, vp); |
| 3557 | } |
| 3558 | } |
| 3559 | |
| 3560 | if (oldvp != NULL) { |
no test coverage detected