Back to index

glibc  2.9
setpriority.c
Go to the documentation of this file.
00001 /* Copyright (C) 1994,95,97,2000,02 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <hurd.h>
00020 #include <hurd/resource.h>
00021 
00022 /* Set the priority of all processes specified by WHICH and WHO
00023    to PRIO.  Returns 0 on success, -1 on errors.  */
00024 int
00025 setpriority (enum __priority_which which, id_t who, int prio)
00026 {
00027   error_t err;
00028   error_t pidloser, priloser;
00029   unsigned int npids, ntasks, nwin, nperm, nacces;
00030 
00031   error_t setonepriority (pid_t pid, struct procinfo *pi)
00032     {
00033       task_t task;
00034       error_t piderr = __USEPORT (PROC, __proc_pid2task (port, pid, &task));
00035       if (piderr == EPERM)
00036        ++nperm;
00037       if (piderr != ESRCH)
00038        {
00039          ++npids;
00040          if (piderr && piderr != EPERM)
00041            pidloser = piderr;
00042        }
00043       if (! piderr)
00044        {
00045          error_t prierr;
00046          ++ntasks;
00047 #ifdef POLICY_TIMESHARE_BASE_COUNT
00048          {
00049            /* XXX This assumes timeshare policy.  */
00050            struct policy_timeshare_base base
00051              = { NICE_TO_MACH_PRIORITY (prio) };
00052            prierr = __task_policy (task, POLICY_TIMESHARE,
00053                                 (policy_base_t) &base,
00054                                 POLICY_TIMESHARE_BASE_COUNT,
00055                                 0, 1);
00056          }
00057 #else
00058          prierr = __task_priority (task, NICE_TO_MACH_PRIORITY (prio), 1);
00059 #endif
00060          __mach_port_deallocate (__mach_task_self (), task);
00061          switch (prierr)
00062            {
00063            case KERN_FAILURE:
00064              ++nacces;
00065              break;
00066            case KERN_SUCCESS:
00067              ++nwin;
00068              break;
00069            case KERN_INVALID_ARGUMENT: /* Task died.  */
00070              --npids;
00071              --ntasks;
00072              break;
00073            default:
00074              priloser = prierr;
00075            }
00076        }
00077       return 0;
00078     }
00079 
00080   npids = ntasks = nwin = nperm = nacces = 0;
00081   pidloser = priloser = 0;
00082   err = _hurd_priority_which_map (which, who, setonepriority, 0);
00083 
00084   if (!err && npids == 0)
00085     /* No error, but no pids found.  */
00086     err = ESRCH;
00087   else if (nperm == npids)
00088     /* Got EPERM from proc_task2pid for every process.  */
00089     err = EPERM;
00090   else if (nacces == ntasks)
00091     /* Got KERN_FAILURE from task_priority for every task.  */
00092     err = EACCES;
00093   else if (nwin == 0)
00094     err = pidloser ?: priloser;
00095 
00096   return err ? __hurd_fail (err) : 0;
00097 }
00098 libc_hidden_def (setpriority)