int procfs_doprocctl(PFS_FILL_ARGS) { int error; struct namemap *nm; if (uio == NULL || uio->uio_rw != UIO_WRITE) return (EOPNOTSUPP); /* * Map signal names into signal generation * or debug control. Unknown commands and/or signals * return EOPNOTSUPP. * * Sending a signal while the process is being debugged * also has the side effect of letting the target continue * to run. There is no way to single-step a signal delivery. */ error = EOPNOTSUPP; sbuf_trim(sb); sbuf_finish(sb); nm = findname(ctlnames, sbuf_data(sb), sbuf_len(sb)); if (nm) { printf("procfs: got a %s command\n", sbuf_data(sb)); error = procfs_control(td, p, nm->nm_val); } else { nm = findname(signames, sbuf_data(sb), sbuf_len(sb)); if (nm) { printf("procfs: got a sig%s\n", sbuf_data(sb)); PROC_LOCK(p); /* This is very broken XXXKSE: */ if (TRACE_WAIT_P(td->td_proc, p)) { p->p_xstat = nm->nm_val; #ifdef FIX_SSTEP /* XXXKSE: */ FIX_SSTEP(FIRST_THREAD_IN_PROC(p)); #endif /* XXXKSE: */ p->p_flag &= ~P_STOPPED_SIG; PROC_SLOCK(p); thread_unsuspend(p); PROC_SUNLOCK(p); } else psignal(p, nm->nm_val); PROC_UNLOCK(p); error = 0; } } return (error); }
static int acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARGS) { struct acpi_cpu_softc *sc; struct sbuf sb; char buf[128]; int i; uintmax_t fract, sum, whole; sc = (struct acpi_cpu_softc *) arg1; sum = 0; for (i = 0; i < sc->cpu_cx_count; i++) sum += sc->cpu_cx_stats[i]; sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN); for (i = 0; i < sc->cpu_cx_count; i++) { if (sum > 0) { whole = (uintmax_t)sc->cpu_cx_stats[i] * 100; fract = (whole % sum) * 100; sbuf_printf(&sb, "%u.%02u%% ", (u_int)(whole / sum), (u_int)(fract / sum)); } else sbuf_printf(&sb, "0.00%% "); } sbuf_printf(&sb, "last %dus", sc->cpu_prev_sleep); sbuf_trim(&sb); sbuf_finish(&sb); sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req); sbuf_delete(&sb); return (0); }
int procfs_doosrel(PFS_FILL_ARGS) { const char *pp; int ov, osrel, i; if (uio == NULL) return (EOPNOTSUPP); if (uio->uio_rw == UIO_READ) { sbuf_printf(sb, "%d\n", p->p_osrel); } else { sbuf_trim(sb); sbuf_finish(sb); pp = sbuf_data(sb); osrel = 0; i = sbuf_len(sb); while (i--) { if (*pp < '0' || *pp > '9') return (EINVAL); ov = osrel * 10 + *pp++ - '0'; if (ov < osrel) return (EINVAL); osrel = ov; } p->p_osrel = osrel; } return (0); }
int procfs_doprocnote(PFS_FILL_ARGS) { sbuf_trim(sb); sbuf_finish(sb); /* send to process's notify function */ return (EOPNOTSUPP); }
static void acpi_cst_support_list(struct acpi_cst_softc *sc) { struct sbuf sb; int i; /* * Set up the list of Cx states */ sbuf_new(&sb, sc->cst_cx_supported, sizeof(sc->cst_cx_supported), SBUF_FIXEDLEN); for (i = 0; i < sc->cst_cx_count; i++) sbuf_printf(&sb, "C%d/%d ", i + 1, sc->cst_cx_states[i].trans_lat); sbuf_trim(&sb); sbuf_finish(&sb); }
static void acpi_cpu_cx_list(struct acpi_cpu_softc *sc) { struct sbuf sb; int i; /* * Set up the list of Cx states */ sc->cpu_non_c3 = 0; sbuf_new(&sb, sc->cpu_cx_supported, sizeof(sc->cpu_cx_supported), SBUF_FIXEDLEN); for (i = 0; i < sc->cpu_cx_count; i++) { sbuf_printf(&sb, "C%d/%d ", i + 1, sc->cpu_cx_states[i].trans_lat); if (sc->cpu_cx_states[i].type < ACPI_STATE_C3) sc->cpu_non_c3 = i; } sbuf_trim(&sb); sbuf_finish(&sb); }
int sys_abort2(struct thread *td, struct abort2_args *uap) { struct proc *p = td->td_proc; struct sbuf *sb; void *uargs[16]; int error, i, sig; /* * Do it right now so we can log either proper call of abort2(), or * note, that invalid argument was passed. 512 is big enough to * handle 16 arguments' descriptions with additional comments. */ sb = sbuf_new(NULL, NULL, 512, SBUF_FIXEDLEN); sbuf_clear(sb); sbuf_printf(sb, "%s(pid %d uid %d) aborted: ", p->p_comm, p->p_pid, td->td_ucred->cr_uid); /* * Since we can't return from abort2(), send SIGKILL in cases, where * abort2() was called improperly */ sig = SIGKILL; /* Prevent from DoSes from user-space. */ if (uap->nargs < 0 || uap->nargs > 16) goto out; if (uap->nargs > 0) { if (uap->args == NULL) goto out; error = copyin(uap->args, uargs, uap->nargs * sizeof(void *)); if (error != 0) goto out; } /* * Limit size of 'reason' string to 128. Will fit even when * maximal number of arguments was chosen to be logged. */ if (uap->why != NULL) { error = sbuf_copyin(sb, uap->why, 128); if (error < 0) goto out; } else { sbuf_printf(sb, "(null)"); } if (uap->nargs > 0) { sbuf_printf(sb, "("); for (i = 0;i < uap->nargs; i++) sbuf_printf(sb, "%s%p", i == 0 ? "" : ", ", uargs[i]); sbuf_printf(sb, ")"); } /* * Final stage: arguments were proper, string has been * successfully copied from userspace, and copying pointers * from user-space succeed. */ sig = SIGABRT; out: if (sig == SIGKILL) { sbuf_trim(sb); sbuf_printf(sb, " (Reason text inaccessible)"); } sbuf_cat(sb, "\n"); sbuf_finish(sb); log(LOG_INFO, "%s", sbuf_data(sb)); sbuf_delete(sb); exit1(td, W_EXITCODE(0, sig)); return (0); }