procfs_ioctl.c revision 113618
10SN/A/*- 29054SN/A * Copyright (c) 2001 Dag-Erling Co�dan Sm�rgrav 30SN/A * All rights reserved. 40SN/A * 50SN/A * Redistribution and use in source and binary forms, with or without 60SN/A * modification, are permitted provided that the following conditions 72362SN/A * are met: 80SN/A * 1. Redistributions of source code must retain the above copyright 92362SN/A * notice, this list of conditions and the following disclaimer 100SN/A * in this position and unchanged. 110SN/A * 2. Redistributions in binary form must reproduce the above copyright 120SN/A * notice, this list of conditions and the following disclaimer in the 130SN/A * documentation and/or other materials provided with the distribution. 140SN/A * 3. The name of the author may not be used to endorse or promote products 150SN/A * derived from this software without specific prior written permission. 160SN/A * 170SN/A * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 180SN/A * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 190SN/A * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 200SN/A * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 212362SN/A * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 222362SN/A * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232362SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 240SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 250SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 260SN/A * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 270SN/A * 282548SN/A * $FreeBSD: head/sys/fs/procfs/procfs_ioctl.c 113618 2003-04-17 22:13:46Z jhb $ 290SN/A */ 300SN/A 310SN/A#include <sys/param.h> 320SN/A#include <sys/lock.h> 330SN/A#include <sys/mutex.h> 340SN/A#include <sys/pioctl.h> 3514781Sdmarkov#include <sys/proc.h> 3613629Savstepan#include <sys/signalvar.h> 370SN/A#include <sys/systm.h> 380SN/A 390SN/A#include <fs/pseudofs/pseudofs.h> 400SN/A#include <fs/procfs/procfs.h> 410SN/A 420SN/A/* 430SN/A * Process ioctls 440SN/A */ 450SN/Aint 462548SN/Aprocfs_ioctl(PFS_IOCTL_ARGS) 470SN/A{ 480SN/A struct procfs_status *ps; 490SN/A int error, flags, sig; 500SN/A 510SN/A PROC_LOCK(p); 520SN/A error = 0; 530SN/A switch (cmd) { 540SN/A case PIOCBIS: 5513629Savstepan p->p_stops |= *(uintptr_t *)data; 560SN/A break; 5713629Savstepan case PIOCBIC: 580SN/A p->p_stops &= ~*(uintptr_t *)data; 590SN/A break; 600SN/A case PIOCSFL: 6113629Savstepan flags = *(uintptr_t *)data; 620SN/A if (flags & PF_ISUGID && (error = suser(td)) != 0) 630SN/A break; 6413629Savstepan p->p_pfsflags = flags; 6513629Savstepan break; 660SN/A case PIOCGFL: 6713629Savstepan *(unsigned int *)data = p->p_pfsflags; 6813629Savstepan break; 690SN/A case PIOCWAIT: 700SN/A while (p->p_step == 0) { 710SN/A /* sleep until p stops */ 720SN/A error = msleep(&p->p_stype, &p->p_mtx, 730SN/A PWAIT|PCATCH, "pioctl", 0); 740SN/A if (error != 0) 750SN/A break; 760SN/A } 770SN/A /* fall through to PIOCSTATUS */ 780SN/A case PIOCSTATUS: 790SN/A ps = (struct procfs_status *)data; 800SN/A ps->state = (p->p_step == 0); 8113629Savstepan ps->flags = 0; /* nope */ 820SN/A ps->events = p->p_stops; 8313629Savstepan ps->why = p->p_step ? p->p_stype : 0; 8413629Savstepan ps->val = p->p_step ? p->p_xstat : 0; 850SN/A break; 860SN/A case PIOCCONT: 870SN/A if (p->p_step == 0) 880SN/A break; 890SN/A sig = *(uintptr_t *)data; 900SN/A if (sig != 0 && !_SIG_VALID(sig)) { 910SN/A error = EINVAL; 920SN/A break; 930SN/A } 940SN/A#if 0 950SN/A p->p_step = 0; 960SN/A if (P_SHOULDSTOP(p)) { 970SN/A p->p_xstat = sig; 980SN/A p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG); 990SN/A mtx_lock_spin(&sched_lock); 1000SN/A thread_unsuspend(p); 1010SN/A mtx_unlock_spin(&sched_lock); 1020SN/A } else if (sig) 1030SN/A psignal(p, sig); 1040SN/A#else 1050SN/A if (sig) 1060SN/A psignal(p, sig); 1070SN/A p->p_step = 0; 10813629Savstepan wakeup(&p->p_step); 10913629Savstepan#endif 1100SN/A break; 1110SN/A default: 1120SN/A error = (ENOTTY); 1130SN/A } 1140SN/A PROC_UNLOCK(p); 1150SN/A 1160SN/A return (error); 1170SN/A} 11813629Savstepan 1190SN/A/* 1200SN/A * Clean up on last close 12113629Savstepan */ 12213629Savstepanint 1230SN/Aprocfs_close(PFS_CLOSE_ARGS) 1240SN/A{ 1250SN/A if (p != NULL && (p->p_pfsflags & PF_LINGER) == 0) { 1260SN/A PROC_LOCK_ASSERT(p, MA_OWNED); 1270SN/A p->p_pfsflags = 0; 1280SN/A p->p_stops = 0; 12913629Savstepan p->p_step = 0; 13013629Savstepan wakeup(&p->p_step); 1310SN/A } 13213629Savstepan return (0); 1330SN/A} 1340SN/A