procfs_ioctl.c revision 87542
187321Sdes/*- 287321Sdes * Copyright (c) 2001 Dag-Erling Co�dan Sm�rgrav 387321Sdes * All rights reserved. 487321Sdes * 587321Sdes * Redistribution and use in source and binary forms, with or without 687321Sdes * modification, are permitted provided that the following conditions 787321Sdes * are met: 887321Sdes * 1. Redistributions of source code must retain the above copyright 987321Sdes * notice, this list of conditions and the following disclaimer 1087321Sdes * in this position and unchanged. 1187321Sdes * 2. Redistributions in binary form must reproduce the above copyright 1287321Sdes * notice, this list of conditions and the following disclaimer in the 1387321Sdes * documentation and/or other materials provided with the distribution. 1487321Sdes * 3. The name of the author may not be used to endorse or promote products 1587321Sdes * derived from this software without specific prior written permission. 1687321Sdes * 1787321Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1887321Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1987321Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2087321Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2187321Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2287321Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2387321Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2487321Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2587321Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2687321Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2787321Sdes * 2887321Sdes * $FreeBSD: head/sys/fs/procfs/procfs_ioctl.c 87542 2001-12-09 00:35:30Z des $ 2987321Sdes */ 3087321Sdes 3187321Sdes#include <sys/param.h> 3287321Sdes#include <sys/lock.h> 3387321Sdes#include <sys/mutex.h> 3487321Sdes#include <sys/pioctl.h> 3587321Sdes#include <sys/proc.h> 3687321Sdes#include <sys/signalvar.h> 3787321Sdes#include <sys/systm.h> 3887321Sdes 3987321Sdes#include <fs/pseudofs/pseudofs.h> 4087321Sdes#include <fs/procfs/procfs.h> 4187321Sdes 4287321Sdes/* 4387321Sdes * Process ioctls 4487321Sdes */ 4587321Sdesint 4687321Sdesprocfs_ioctl(PFS_IOCTL_ARGS) 4787321Sdes{ 4887321Sdes struct procfs_status *ps; 4987542Sdes int error, flags, sig; 5087321Sdes 5187321Sdes PROC_LOCK(p); 5287321Sdes error = 0; 5387321Sdes switch (cmd) { 5487321Sdes case PIOCBIS: 5587321Sdes p->p_stops |= *(unsigned int *)data; 5687321Sdes break; 5787321Sdes case PIOCBIC: 5887321Sdes p->p_stops &= ~*(unsigned int *)data; 5987321Sdes break; 6087321Sdes case PIOCSFL: 6187542Sdes flags = *(unsigned int *)data; 6287542Sdes if (flags & PF_ISUGID && (error = suser(td->td_proc)) != 0) 6387542Sdes break; 6487542Sdes p->p_pfsflags = flags; 6587321Sdes break; 6687321Sdes case PIOCGFL: 6787542Sdes *(unsigned int *)data = p->p_pfsflags; 6887321Sdes break; 6987321Sdes case PIOCWAIT: 7087321Sdes while (p->p_step == 0) { 7187321Sdes /* sleep until p stops */ 7287321Sdes error = msleep(&p->p_stype, &p->p_mtx, 7387321Sdes PWAIT|PCATCH, "pioctl", 0); 7487321Sdes if (error != 0) 7587321Sdes break; 7687321Sdes } 7787321Sdes /* fall through to PIOCSTATUS */ 7887321Sdes case PIOCSTATUS: 7987321Sdes ps = (struct procfs_status *)data; 8087321Sdes ps->state = (p->p_step == 0); 8187321Sdes ps->flags = 0; /* nope */ 8287321Sdes ps->events = p->p_stops; 8387321Sdes ps->why = p->p_step ? p->p_stype : 0; 8487321Sdes ps->val = p->p_step ? p->p_xstat : 0; 8587321Sdes break; 8687321Sdes case PIOCCONT: 8787542Sdes if (p->p_step == 0) 8887321Sdes break; 8987321Sdes sig = *(int *)data; 9087542Sdes if (sig != 0 && !_SIG_VALID(sig)) { 9187321Sdes error = EINVAL; 9287321Sdes break; 9387321Sdes } 9487321Sdes#if 0 9587321Sdes mtx_lock_spin(&sched_lock); 9687321Sdes p->p_step = 0; 9787321Sdes if (p->p_stat == SSTOP) { 9887321Sdes p->p_xstat = sig; 9987321Sdes setrunnable(&p->p_thread); 10087321Sdes mtx_unlock_spin(&sched_lock); 10187321Sdes } else { 10287321Sdes mtx_unlock_spin(&sched_lock); 10387321Sdes if (sig) 10487321Sdes psignal(p, sig); 10587321Sdes } 10687321Sdes#else 10787321Sdes if (sig) 10887321Sdes psignal(p, sig); 10987542Sdes p->p_step = 0; 11087321Sdes wakeup(&p->p_step); 11187321Sdes#endif 11287321Sdes break; 11387321Sdes default: 11487321Sdes error = (ENOTTY); 11587321Sdes } 11687321Sdes PROC_UNLOCK(p); 11787321Sdes 11887321Sdes return (error); 11987321Sdes} 12087321Sdes 12187321Sdes/* 12287321Sdes * Clean up on last close 12387321Sdes */ 12487321Sdesint 12587321Sdesprocfs_close(PFS_CLOSE_ARGS) 12687321Sdes{ 12787321Sdes if (p != NULL && (p->p_pfsflags & PF_LINGER) == 0) { 12887321Sdes p->p_pfsflags = 0; 12987321Sdes p->p_stops = 0; 13087321Sdes p->p_step = 0; 13187321Sdes wakeup(&p->p_step); 13287321Sdes } 13387321Sdes return (0); 13487321Sdes} 135