* corefile_open(comm, uid, pid, td, compress, vpp, namep) * Expand the name described in corefilename, using name, uid, and pid * and open/create core file. * corefilename is a printf-like string, with three format specifiers: * %N name of process ("name") * %P process id (pid) * %U user id (uid) * For example, "%N.core" is the default; they can be disabled completely * by using "/dev/null
| 3598 | * This is controlled by the sysctl variable kern.corefile (see above). |
| 3599 | */ |
| 3600 | static int |
| 3601 | corefile_open(const char *comm, uid_t uid, pid_t pid, struct thread *td, |
| 3602 | int compress, int signum, struct vnode **vpp, char **namep) |
| 3603 | { |
| 3604 | struct sbuf sb; |
| 3605 | struct nameidata nd; |
| 3606 | const char *format; |
| 3607 | char *hostname, *name; |
| 3608 | int cmode, error, flags, i, indexpos, indexlen, oflags, ncores; |
| 3609 | |
| 3610 | hostname = NULL; |
| 3611 | format = corefilename; |
| 3612 | name = malloc(MAXPATHLEN, M_TEMP, M_WAITOK | M_ZERO); |
| 3613 | indexlen = 0; |
| 3614 | indexpos = -1; |
| 3615 | ncores = num_cores; |
| 3616 | (void)sbuf_new(&sb, name, MAXPATHLEN, SBUF_FIXEDLEN); |
| 3617 | sx_slock(&corefilename_lock); |
| 3618 | for (i = 0; format[i] != '\0'; i++) { |
| 3619 | switch (format[i]) { |
| 3620 | case '%': /* Format character */ |
| 3621 | i++; |
| 3622 | switch (format[i]) { |
| 3623 | case '%': |
| 3624 | sbuf_putc(&sb, '%'); |
| 3625 | break; |
| 3626 | case 'H': /* hostname */ |
| 3627 | if (hostname == NULL) { |
| 3628 | hostname = malloc(MAXHOSTNAMELEN, |
| 3629 | M_TEMP, M_WAITOK); |
| 3630 | } |
| 3631 | getcredhostname(td->td_ucred, hostname, |
| 3632 | MAXHOSTNAMELEN); |
| 3633 | sbuf_printf(&sb, "%s", hostname); |
| 3634 | break; |
| 3635 | case 'I': /* autoincrementing index */ |
| 3636 | if (indexpos != -1) { |
| 3637 | sbuf_printf(&sb, "%%I"); |
| 3638 | break; |
| 3639 | } |
| 3640 | |
| 3641 | indexpos = sbuf_len(&sb); |
| 3642 | sbuf_printf(&sb, "%u", ncores - 1); |
| 3643 | indexlen = sbuf_len(&sb) - indexpos; |
| 3644 | break; |
| 3645 | case 'N': /* process name */ |
| 3646 | sbuf_printf(&sb, "%s", comm); |
| 3647 | break; |
| 3648 | case 'P': /* process id */ |
| 3649 | sbuf_printf(&sb, "%u", pid); |
| 3650 | break; |
| 3651 | case 'S': /* signal number */ |
| 3652 | sbuf_printf(&sb, "%i", signum); |
| 3653 | break; |
| 3654 | case 'U': /* user id */ |
| 3655 | sbuf_printf(&sb, "%u", uid); |
| 3656 | break; |
| 3657 | default: |
no test coverage detected