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