1/* Copyright (C) 1994-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
17
18#include <hurd.h>
19#include <hurd/resource.h>
20
21/* Set the priority of all processes specified by WHICH and WHO
22 to PRIO. Returns 0 on success, -1 on errors. */
23int
24__setpriority (enum __priority_which which, id_t who, int prio)
25{
26 error_t err;
27 error_t pidloser, priloser;
28 unsigned int npids, ntasks, nwin, nperm, nacces;
29
30 error_t setonepriority (pid_t pid, struct procinfo *pi)
31 {
32 task_t task;
33 error_t piderr = __USEPORT (PROC, __proc_pid2task (port, pid, &task));
34 if (piderr == EPERM)
35 ++nperm;
36 if (piderr != ESRCH)
37 {
38 ++npids;
39 if (piderr && piderr != EPERM)
40 pidloser = piderr;
41 }
42 if (! piderr)
43 {
44 error_t prierr;
45 ++ntasks;
46#ifdef POLICY_TIMESHARE_BASE_COUNT
47 {
48 /* XXX This assumes timeshare policy. */
49 struct policy_timeshare_base base
50 = { NICE_TO_MACH_PRIORITY (prio) };
51 prierr = __task_policy (task, POLICY_TIMESHARE,
52 (policy_base_t) &base,
53 POLICY_TIMESHARE_BASE_COUNT,
54 0, 1);
55 }
56#else
57 prierr = __task_priority (task, NICE_TO_MACH_PRIORITY (prio), 1);
58#endif
59 __mach_port_deallocate (__mach_task_self (), task);
60 switch (prierr)
61 {
62 case KERN_FAILURE:
63 ++nacces;
64 break;
65 case KERN_SUCCESS:
66 ++nwin;
67 break;
68 case KERN_INVALID_ARGUMENT: /* Task died. */
69 --npids;
70 --ntasks;
71 break;
72 default:
73 priloser = prierr;
74 }
75 }
76 return 0;
77 }
78
79 npids = ntasks = nwin = nperm = nacces = 0;
80 pidloser = priloser = 0;
81 err = _hurd_priority_which_map (which, who, setonepriority, 0);
82
83 if (!err && npids == 0)
84 /* No error, but no pids found. */
85 err = ESRCH;
86 else if (nperm == npids)
87 /* Got EPERM from proc_task2pid for every process. */
88 err = EPERM;
89 else if (nacces == ntasks)
90 /* Got KERN_FAILURE from task_priority for every task. */
91 err = EACCES;
92 else if (nwin == 0)
93 err = pidloser ?: priloser;
94
95 return err ? __hurd_fail (err) : 0;
96}
97libc_hidden_def (__setpriority)
98weak_alias (__setpriority, setpriority)
99

source code of glibc/sysdeps/mach/hurd/setpriority.c