hurdprio.c 2.6 KB

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