(root)/
glibc-2.38/
hurd/
hurdprio.c
       1  /* Support code for dealing with priorities in the Hurd.
       2     Copyright (C) 1994-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <hurd.h>
      20  #include <hurd/resource.h>
      21  #include <sys/mman.h>
      22  #include <unistd.h>
      23  
      24  error_t
      25  _hurd_priority_which_map (enum __priority_which which, int who,
      26  			  error_t (*function) (pid_t, struct procinfo *),
      27  			  int pi_flags)
      28  {
      29    mach_msg_type_number_t npids = 64, i;
      30    pid_t pidbuf[npids], *pids = pidbuf;
      31    error_t err;
      32    struct procinfo *pip;
      33    int pibuf[sizeof *pip + 5 * sizeof (pip->threadinfos[0])], *pi = pibuf;
      34    mach_msg_type_number_t pisize = sizeof (pibuf) / sizeof (int);
      35  
      36    switch (which)
      37      {
      38      default:
      39        return EINVAL;
      40  
      41      case PRIO_PROCESS:
      42        err = (*function) (who ?: getpid (), 0); /* XXX special-case self? */
      43        break;
      44  
      45      case PRIO_PGRP:
      46        err = __USEPORT (PROC, __proc_getpgrppids (port, who, &pids, &npids));
      47        for (i = 0; !err && i < npids; ++i)
      48  	err = (*function) (pids[i], 0);
      49        break;
      50  
      51      case PRIO_USER:
      52        if (who == 0)
      53  	who = __geteuid ();
      54        err = __USEPORT (PROC, __proc_getallpids (port, &pids, &npids));
      55        for (i = 0; !err && i < npids; ++i)
      56  	{
      57  	  /* Get procinfo to check the owner.  */
      58  	  int *oldpi = pi;
      59  	  mach_msg_type_number_t oldpisize = pisize;
      60  	  char *tw = 0;
      61  	  mach_msg_type_number_t twsz = 0;
      62  	  err = __USEPORT (PROC, __proc_getprocinfo (port, pids[i],
      63  						     &pi_flags,
      64  						     &pi, &pisize,
      65  						     &tw, &twsz));
      66  	  if (!err)
      67  	    {
      68  	      if (twsz)		/* Gratuitous.  */
      69  		__munmap (tw, twsz);
      70  	      if (pi != oldpi && oldpi != pibuf)
      71  		/* Old buffer from last call was not reused; free it.  */
      72  		__munmap (oldpi, oldpisize * sizeof pi[0]);
      73  
      74  	      pip = (struct procinfo *) pi;
      75  	      if (pip->owner == (uid_t) who)
      76  		err = (*function) (pids[i], pip);
      77  	    }
      78  	}
      79        break;
      80      }
      81  
      82    if (pids != pidbuf)
      83      __munmap (pids, npids * sizeof pids[0]);
      84    if (pi != pibuf)
      85      __munmap (pi, pisize * sizeof pi[0]);
      86  
      87    return err;
      88  }