procfs_ioctl.c revision 101901
1/*-
2 * Copyright (c) 2001 Dag-Erling Co�dan Sm�rgrav
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer
10 *    in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 *      $FreeBSD: head/sys/fs/procfs/procfs_ioctl.c 101901 2002-08-15 06:16:10Z jake $
29 */
30
31#include <sys/param.h>
32#include <sys/lock.h>
33#include <sys/mutex.h>
34#include <sys/pioctl.h>
35#include <sys/proc.h>
36#include <sys/signalvar.h>
37#include <sys/systm.h>
38
39#include <fs/pseudofs/pseudofs.h>
40#include <fs/procfs/procfs.h>
41
42/*
43 * Process ioctls
44 */
45int
46procfs_ioctl(PFS_IOCTL_ARGS)
47{
48	struct procfs_status *ps;
49	int error, flags, sig;
50
51	PROC_LOCK(p);
52	error = 0;
53	switch (cmd) {
54	case PIOCBIS:
55		p->p_stops |= *(uintptr_t *)data;
56		break;
57	case PIOCBIC:
58		p->p_stops &= ~*(uintptr_t *)data;
59		break;
60	case PIOCSFL:
61		flags = *(uintptr_t *)data;
62		if (flags & PF_ISUGID && (error = suser(td)) != 0)
63			break;
64		p->p_pfsflags = flags;
65		break;
66	case PIOCGFL:
67		*(unsigned int *)data = p->p_pfsflags;
68		break;
69	case PIOCWAIT:
70		while (p->p_step == 0) {
71			/* sleep until p stops */
72			error = msleep(&p->p_stype, &p->p_mtx,
73			    PWAIT|PCATCH, "pioctl", 0);
74			if (error != 0)
75				break;
76		}
77		/* fall through to PIOCSTATUS */
78	case PIOCSTATUS:
79		ps = (struct procfs_status *)data;
80		ps->state = (p->p_step == 0);
81		ps->flags = 0; /* nope */
82		ps->events = p->p_stops;
83		ps->why = p->p_step ? p->p_stype : 0;
84		ps->val = p->p_step ? p->p_xstat : 0;
85		break;
86	case PIOCCONT:
87		if (p->p_step == 0)
88			break;
89		sig = *(uintptr_t *)data;
90		if (sig != 0 && !_SIG_VALID(sig)) {
91			error = EINVAL;
92			break;
93		}
94#if 0
95		mtx_lock_spin(&sched_lock);
96		p->p_step = 0;
97		if (P_SHOULDSTOP(p)) {
98			p->p_xstat = sig;
99			p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SGNL);
100			FOREACH_THREAD_IN_PROC(p, td)
101				setrunnable(td);	/* XXX Totally bogus */
102			mtx_unlock_spin(&sched_lock);
103		} else {
104			mtx_unlock_spin(&sched_lock);
105			if (sig)
106				psignal(p, sig);
107		}
108#else
109		if (sig)
110			psignal(p, sig);
111		p->p_step = 0;
112		wakeup(&p->p_step);
113#endif
114		break;
115	default:
116		error = (ENOTTY);
117	}
118	PROC_UNLOCK(p);
119
120	return (error);
121}
122
123/*
124 * Clean up on last close
125 */
126int
127procfs_close(PFS_CLOSE_ARGS)
128{
129	if (p != NULL && (p->p_pfsflags & PF_LINGER) == 0) {
130		p->p_pfsflags = 0;
131		p->p_stops = 0;
132		p->p_step = 0;
133		wakeup(&p->p_step);
134	}
135	return (0);
136}
137