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