The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/procfs/procfs_ioctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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$
   29  */
   30 
   31 #include "opt_compat.h"
   32 
   33 #include <sys/param.h>
   34 #include <sys/lock.h>
   35 #include <sys/mutex.h>
   36 #include <sys/pioctl.h>
   37 #include <sys/priv.h>
   38 #include <sys/proc.h>
   39 #include <sys/signalvar.h>
   40 #include <sys/systm.h>
   41 
   42 #include <fs/pseudofs/pseudofs.h>
   43 #include <fs/procfs/procfs.h>
   44 
   45 #ifdef COMPAT_FREEBSD32
   46 struct procfs_status32 {
   47         int     state;  /* Running, stopped, something else? */
   48         int     flags;  /* Any flags */
   49         unsigned int    events; /* Events to stop on */
   50         int     why;    /* What event, if any, proc stopped on */
   51         unsigned int    val;    /* Any extra data */
   52 };
   53 
   54 #define PIOCWAIT32      _IOR('p', 4, struct procfs_status32)
   55 #define PIOCSTATUS32    _IOR('p', 6, struct procfs_status32)
   56 #endif
   57 
   58 /*
   59  * Process ioctls
   60  */
   61 int
   62 procfs_ioctl(PFS_IOCTL_ARGS)
   63 {
   64         struct procfs_status *ps;
   65 #ifdef COMPAT_FREEBSD32
   66         struct procfs_status32 *ps32;
   67 #endif
   68         int error, flags, sig;
   69 #ifdef COMPAT_FREEBSD6
   70         int ival;
   71 #endif
   72         static struct timeval lasttime;
   73         static struct timeval interval = { .tv_sec = 1, .tv_usec = 0 };
   74 
   75         KASSERT(p != NULL,
   76             ("%s() called without a process", __func__));
   77         PROC_LOCK_ASSERT(p, MA_OWNED);
   78 
   79         switch (cmd) {
   80 #if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
   81         case _IOC(IOC_IN, 'p', 1, 0):
   82 #endif
   83 #ifdef COMPAT_FREEBSD6
   84         case _IO('p', 1):
   85 #endif
   86         case PIOCBIS:
   87 #if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
   88         case _IOC(IOC_IN, 'p', 2, 0):
   89 #endif
   90 #ifdef COMPAT_FREEBSD6
   91         case _IO('p', 2):
   92 #endif
   93         case PIOCBIC:
   94 #if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
   95         case _IOC(IOC_IN, 'p', 3, 0):
   96 #endif
   97 #ifdef COMPAT_FREEBSD6
   98         case _IO('p', 3):
   99 #endif
  100         case PIOCSFL:
  101         case PIOCGFL:
  102         case PIOCWAIT:
  103         case PIOCSTATUS:
  104 #ifdef COMPAT_FREEBSD32
  105         case PIOCWAIT32:
  106         case PIOCSTATUS32:
  107 #endif
  108 #if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
  109         case _IOC(IOC_IN, 'p', 5, 0):
  110 #endif
  111 #ifdef COMPAT_FREEBSD6
  112         case _IO('p', 5):
  113 #endif
  114         case PIOCCONT:
  115                 if (ratecheck(&lasttime, &interval) != 0)
  116                         gone_in(13, "procfs-based process debugging");
  117                 break;
  118         }
  119 
  120         error = 0;
  121         switch (cmd) {
  122 #if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
  123         case _IOC(IOC_IN, 'p', 1, 0):
  124 #endif
  125 #ifdef COMPAT_FREEBSD6
  126         case _IO('p', 1):
  127                 ival = IOCPARM_IVAL(data);
  128                 data = &ival;
  129 #endif
  130         case PIOCBIS:
  131                 p->p_stops |= *(unsigned int *)data;
  132                 break;
  133 #if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
  134         case _IOC(IOC_IN, 'p', 2, 0):
  135 #endif
  136 #ifdef COMPAT_FREEBSD6
  137         case _IO('p', 2):
  138                 ival = IOCPARM_IVAL(data);
  139                 data = &ival;
  140 #endif
  141         case PIOCBIC:
  142                 p->p_stops &= ~*(unsigned int *)data;
  143                 break;
  144 #if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
  145         case _IOC(IOC_IN, 'p', 3, 0):
  146 #endif
  147 #ifdef COMPAT_FREEBSD6
  148         case _IO('p', 3):
  149                 ival = IOCPARM_IVAL(data);
  150                 data = &ival;
  151 #endif
  152         case PIOCSFL:
  153                 flags = *(unsigned int *)data;
  154                 if (flags & PF_ISUGID) {
  155                         /*
  156                          * XXXRW: Is this specific check required here, as
  157                          * p_candebug() should implement it, or other checks
  158                          * are missing.
  159                          */
  160                         error = priv_check(td, PRIV_DEBUG_SUGID);
  161                         if (error)
  162                                 break;
  163                 }
  164                 p->p_pfsflags = flags;
  165                 break;
  166         case PIOCGFL:
  167                 *(unsigned int *)data = p->p_pfsflags;
  168                 break;
  169         case PIOCWAIT:
  170                 while (p->p_step == 0 && (p->p_flag & P_WEXIT) == 0) {
  171                         /* sleep until p stops */
  172                         _PHOLD(p);
  173                         error = msleep(&p->p_stype, &p->p_mtx,
  174                             PWAIT|PCATCH, "pioctl", 0);
  175                         _PRELE(p);
  176                         if (error != 0)
  177                                 break;
  178                 }
  179                 /* fall through to PIOCSTATUS */
  180         case PIOCSTATUS:
  181                 ps = (struct procfs_status *)data;
  182                 ps->state = (p->p_step == 0);
  183                 ps->flags = 0; /* nope */
  184                 ps->events = p->p_stops;
  185                 ps->why = p->p_step ? p->p_stype : 0;
  186                 ps->val = p->p_step ? p->p_xsig : 0;
  187                 break;
  188 #ifdef COMPAT_FREEBSD32
  189         case PIOCWAIT32:
  190                 while (p->p_step == 0 && (p->p_flag & P_WEXIT) == 0) {
  191                         /* sleep until p stops */
  192                         _PHOLD(p);
  193                         error = msleep(&p->p_stype, &p->p_mtx,
  194                             PWAIT|PCATCH, "pioctl", 0);
  195                         _PRELE(p);
  196                         if (error != 0)
  197                                 break;
  198                 }
  199                 /* fall through to PIOCSTATUS32 */
  200         case PIOCSTATUS32:
  201                 ps32 = (struct procfs_status32 *)data;
  202                 ps32->state = (p->p_step == 0);
  203                 ps32->flags = 0; /* nope */
  204                 ps32->events = p->p_stops;
  205                 ps32->why = p->p_step ? p->p_stype : 0;
  206                 ps32->val = p->p_step ? p->p_xsig : 0;
  207                 break;
  208 #endif
  209 #if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
  210         case _IOC(IOC_IN, 'p', 5, 0):
  211 #endif
  212 #ifdef COMPAT_FREEBSD6
  213         case _IO('p', 5):
  214                 ival = IOCPARM_IVAL(data);
  215                 data = &ival;
  216 #endif
  217         case PIOCCONT:
  218                 if (p->p_step == 0)
  219                         break;
  220                 sig = *(unsigned int *)data;
  221                 if (sig != 0 && !_SIG_VALID(sig)) {
  222                         error = EINVAL;
  223                         break;
  224                 }
  225 #if 0
  226                 p->p_step = 0;
  227                 if (P_SHOULDSTOP(p)) {
  228                         p->p_xsig = sig;
  229                         p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG);
  230                         PROC_SLOCK(p);
  231                         thread_unsuspend(p);
  232                         PROC_SUNLOCK(p);
  233                 } else if (sig)
  234                         kern_psignal(p, sig);
  235 #else
  236                 if (sig)
  237                         kern_psignal(p, sig);
  238                 p->p_step = 0;
  239                 wakeup(&p->p_step);
  240 #endif
  241                 break;
  242         default:
  243                 error = (ENOTTY);
  244         }
  245 
  246         return (error);
  247 }
  248 
  249 /*
  250  * Clean up on last close
  251  */
  252 int
  253 procfs_close(PFS_CLOSE_ARGS)
  254 {
  255         if (p != NULL && (p->p_pfsflags & PF_LINGER) == 0) {
  256                 PROC_LOCK_ASSERT(p, MA_OWNED);
  257                 p->p_pfsflags = 0;
  258                 p->p_stops = 0;
  259                 p->p_step = 0;
  260                 wakeup(&p->p_step);
  261         }
  262         return (0);
  263 }

Cache object: 7ccc4108cdcd11d1c700039b7e9d4cf9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.