Back to index

glibc  2.9
hurdprio.c
Go to the documentation of this file.
00001 /* Support code for dealing with priorities in the Hurd.
00002    Copyright (C) 1994,95,96,97,99 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <hurd.h>
00021 #include <hurd/resource.h>
00022 #include <sys/mman.h>
00023 #include <unistd.h>
00024 
00025 error_t
00026 _hurd_priority_which_map (enum __priority_which which, int who,
00027                        error_t (*function) (pid_t, struct procinfo *),
00028                        int pi_flags)
00029 {
00030   mach_msg_type_number_t npids = 64, i;
00031   pid_t pidbuf[npids], *pids = pidbuf;
00032   error_t err;
00033   struct procinfo *pip;
00034   int pibuf[sizeof *pip + 5 * sizeof (pip->threadinfos[0])], *pi = pibuf;
00035   mach_msg_type_number_t pisize = sizeof (pibuf) / sizeof (int);
00036 
00037   switch (which)
00038     {
00039     default:
00040       return EINVAL;
00041 
00042     case PRIO_PROCESS:
00043       err = (*function) (who ?: getpid (), 0); /* XXX special-case self? */
00044       break;
00045 
00046     case PRIO_PGRP:
00047       err = __USEPORT (PROC, __proc_getpgrppids (port, who, &pids, &npids));
00048       for (i = 0; !err && i < npids; ++i)
00049        err = (*function) (pids[i], 0);
00050       break;
00051 
00052     case PRIO_USER:
00053       if (who == 0)
00054        who = geteuid ();
00055       err = __USEPORT (PROC, __proc_getallpids (port, &pids, &npids));
00056       for (i = 0; !err && i < npids; ++i)
00057        {
00058          /* Get procinfo to check the owner.  */
00059          int *oldpi = pi;
00060          mach_msg_type_number_t oldpisize = pisize;
00061          char *tw = 0;
00062          size_t twsz = 0;
00063          err = __USEPORT (PROC, __proc_getprocinfo (port, pids[i],
00064                                                &pi_flags,
00065                                                &pi, &pisize,
00066                                                &tw, &twsz));
00067          if (!err)
00068            {
00069              if (twsz)             /* Gratuitous.  */
00070               __munmap (tw, twsz);
00071              if (pi != oldpi && oldpi != pibuf)
00072               /* Old buffer from last call was not reused; free it.  */
00073               __munmap (oldpi, oldpisize * sizeof pi[0]);
00074 
00075              pip = (struct procinfo *) pi;
00076              if (pip->owner == (uid_t) who)
00077               err = (*function) (pids[i], pip);
00078            }
00079        }
00080       break;
00081     }
00082 
00083   if (pids != pidbuf)
00084     __munmap (pids, npids * sizeof pids[0]);
00085   if (pi != pibuf)
00086     __munmap (pi, pisize * sizeof pi[0]);
00087 
00088   return err;
00089 }