root/miscfs/procfs/procfs_cmdline.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. procfs_docmdline

    1 /*      $OpenBSD: procfs_cmdline.c,v 1.8 2007/06/18 08:30:07 jasper Exp $       */
    2 /*      $NetBSD: procfs_cmdline.c,v 1.3 1999/03/13 22:26:48 thorpej Exp $       */
    3 
    4 /*
    5  * Copyright (c) 1999 Jaromir Dolecek <dolecek@ics.muni.cz>
    6  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    7  * All rights reserved.
    8  *
    9  * This code is derived from software contributed to The NetBSD Foundation
   10  * by Jaromir Dolecek.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *      This product includes software developed by the NetBSD
   23  *      Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 #include <sys/param.h>
   42 #include <sys/types.h>
   43 #include <sys/systm.h>
   44 #include <sys/syslimits.h>
   45 #include <sys/proc.h>
   46 #include <sys/vnode.h>
   47 #include <sys/exec.h>
   48 #include <sys/malloc.h>
   49 #include <miscfs/procfs/procfs.h>
   50 #include <uvm/uvm_extern.h>
   51 
   52 /*
   53  * code for returning process's command line arguments
   54  */
   55 int
   56 procfs_docmdline(struct proc *curp, struct proc *p, struct pfsnode *pfs, struct uio *uio)
   57 {
   58         struct ps_strings pss;
   59         int count, error, i;
   60         size_t len, xlen, upper_bound;
   61         struct uio auio;
   62         struct iovec aiov;
   63         vaddr_t argv;
   64         char *arg;
   65 
   66         /* Don't allow writing. */
   67         if (uio->uio_rw != UIO_READ)
   68                 return (EOPNOTSUPP);
   69 
   70         /*
   71          * Allocate a temporary buffer to hold the arguments.
   72          */
   73         arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
   74 
   75         /*
   76          * Zombies don't have a stack, so we can't read their psstrings.
   77          * System processes also don't have a user stack.  This is what
   78          * ps(1) would display.
   79          */
   80         if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) {
   81                 len = snprintf(arg, PAGE_SIZE, "(%s)", p->p_comm);
   82                 if (uio->uio_offset >= (off_t)len)
   83                         error = 0;
   84                 else
   85                         error = uiomove(arg, len - uio->uio_offset, uio);
   86                 
   87                 free(arg, M_TEMP);
   88                 return (error); 
   89         }
   90 
   91         /*
   92          * NOTE: Don't bother doing a process_checkioperm() here
   93          * because the psstrings info is available by using ps(1),
   94          * so it's not like there's anything to protect here.
   95          */
   96 
   97         /*
   98          * Lock the process down in memory.
   99          */
  100         /* XXXCDC: how should locking work here? */
  101         if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) {
  102                 free(arg, M_TEMP);
  103                 return (EFAULT);
  104         }
  105         p->p_vmspace->vm_refcnt++;      /* XXX */
  106 
  107         /*
  108          * Read in the ps_strings structure.
  109          */
  110         aiov.iov_base = &pss;
  111         aiov.iov_len = sizeof(pss);
  112         auio.uio_iov = &aiov;
  113         auio.uio_iovcnt = 1;
  114         auio.uio_offset = (vaddr_t)PS_STRINGS;
  115         auio.uio_resid = sizeof(pss);
  116         auio.uio_segflg = UIO_SYSSPACE;
  117         auio.uio_rw = UIO_READ;
  118         auio.uio_procp = NULL;
  119         error = uvm_io(&p->p_vmspace->vm_map, &auio, 0);
  120         if (error)
  121                 goto bad;
  122 
  123         /*
  124          * Now read the address of the argument vector.
  125          */
  126         aiov.iov_base = &argv;
  127         aiov.iov_len = sizeof(argv);
  128         auio.uio_iov = &aiov;
  129         auio.uio_iovcnt = 1;
  130         auio.uio_offset = (vaddr_t)pss.ps_argvstr;
  131         auio.uio_resid = sizeof(argv);
  132         auio.uio_segflg = UIO_SYSSPACE;
  133         auio.uio_rw = UIO_READ; 
  134         auio.uio_procp = NULL;
  135         error = uvm_io(&p->p_vmspace->vm_map, &auio, 0);
  136         if (error)
  137                 goto bad;
  138 
  139         /*
  140          * Now copy in the actual argument vector, one byte at a time,
  141          * since we don't know how long the vector is (though, we do
  142          * know how many NUL-terminated strings are in the vector).
  143          */
  144         len = 0;
  145         count = pss.ps_nargvstr;
  146         upper_bound = round_page(uio->uio_offset + uio->uio_resid);
  147         for (; count && len < upper_bound; len += xlen) {
  148                 aiov.iov_base = arg;
  149                 aiov.iov_len = PAGE_SIZE;
  150                 auio.uio_iov = &aiov;
  151                 auio.uio_iovcnt = 1;
  152                 auio.uio_offset = argv + len;
  153                 xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK);
  154                 auio.uio_resid = xlen;
  155                 auio.uio_segflg = UIO_SYSSPACE;
  156                 auio.uio_rw = UIO_READ;
  157                 auio.uio_procp = NULL;
  158                 error = uvm_io(&p->p_vmspace->vm_map, &auio, 0);
  159                 if (error)
  160                         goto bad;
  161 
  162                 for (i = 0; i < xlen && count != 0; i++) {
  163                         if (arg[i] == '\0')
  164                                 count--;        /* one full string */
  165                 }
  166 
  167                 if (count == 0)
  168                         i--;                /* exclude the final NUL */
  169 
  170                 if (len + i > uio->uio_offset) {
  171                         /* Have data in this page, copy it out */
  172                         error = uiomove(arg + uio->uio_offset - len,
  173                             i + len - uio->uio_offset, uio);
  174                         if (error || uio->uio_resid <= 0)
  175                                 break;
  176                 }
  177         }
  178 
  179 
  180  bad:
  181         uvmspace_free(p->p_vmspace);
  182         free(arg, M_TEMP);
  183         return (error);
  184 }

/* [<][>][^][v][top][bottom][index][help] */