summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2005-01-26 13:07:48 +0000
committerCorinna Vinschen <corinna@vinschen.de>2005-01-26 13:07:48 +0000
commit0f72b906372e740d0f0eb5f3845f602defea7130 (patch)
tree7f88521dab8a016f8814a8ae1b04757b431ff1cf
parentb7a51e1b2a28136ed641f62aab34a9feb159a462 (diff)
downloadcygnal-0f72b906372e740d0f0eb5f3845f602defea7130.tar.gz
cygnal-0f72b906372e740d0f0eb5f3845f602defea7130.tar.bz2
cygnal-0f72b906372e740d0f0eb5f3845f602defea7130.zip
* syscalls.cc (setpriority): Implement PRIO_PGRP, PRIO_USER and
setting priority in other Cygwin processes. (getpriority): Implement PRIO_PGRP, PRIO_USER and getting nice value from other processes.
-rw-r--r--winsup/cygwin/ChangeLog7
-rw-r--r--winsup/cygwin/syscalls.cc126
2 files changed, 123 insertions, 10 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index db63828a4..babb9f846 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,10 @@
+2005-01-25 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (setpriority): Implement PRIO_PGRP, PRIO_USER and
+ setting priority in other Cygwin processes.
+ (getpriority): Implement PRIO_PGRP, PRIO_USER and getting nice value
+ from other processes.
+
2005-01-26 Pierre Humblet <pierre.humblet@ieee.org>
* path.cc (path_conv::check): Return ENOTDIR rather than ENOENT
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 7ea36273b..8548f5e4a 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -2445,33 +2445,139 @@ memccpy (_PTR out, const _PTR in, int c, size_t len)
extern "C" int
setpriority (int which, id_t who, int value)
{
- /* TODO: Support PRIO_PGRP and PRIO_USER. */
- if (which != PRIO_PROCESS || (who != 0 && (pid_t) who != myself->pid))
+ DWORD prio = nice_to_winprio (value);
+ int error = 0;
+
+ switch (which)
{
+ case PRIO_PROCESS:
+ if (!who)
+ who = myself->pid;
+ if ((pid_t) who == myself->pid)
+ {
+ if (!SetPriorityClass (hMainProc, prio))
+ {
+ set_errno (EACCES);
+ return -1;
+ }
+ myself->nice = value;
+ debug_printf ("Set nice to %d", myself->nice);
+ return 0;
+ }
+ break;
+ case PRIO_PGRP:
+ if (!who)
+ who = myself->pgid;
+ break;
+ case PRIO_USER:
+ if (!who)
+ who = myself->uid;
+ break;
+ default:
set_errno (EINVAL);
return -1;
}
- DWORD prio = nice_to_winprio (value);
- if (SetPriorityClass (hMainProc, prio) == FALSE)
+ winpids pids ((DWORD) PID_MAP_RW);
+ for (DWORD i = 0; i < pids.npids; ++i)
{
- __seterrno ();
+ _pinfo *p = pids[i];
+ if (p)
+ {
+ switch (which)
+ {
+ case PRIO_PROCESS:
+ if ((pid_t) who != p->pid)
+ continue;
+ break;
+ case PRIO_PGRP:
+ if ((pid_t) who != p->pgid)
+ continue;
+ break;
+ case PRIO_USER:
+ if ((__uid32_t) who != p->uid)
+ continue;
+ break;
+ }
+ HANDLE proc_h = OpenProcess (PROCESS_SET_INFORMATION, FALSE,
+ p->dwProcessId);
+ if (!proc_h)
+ error = EPERM;
+ else
+ {
+ if (!SetPriorityClass (proc_h, prio))
+ error = EACCES;
+ else
+ p->nice = value;
+ CloseHandle (proc_h);
+ }
+ }
+ }
+ pids.reset ();
+ if (error)
+ {
+ set_errno (error);
return -1;
}
- myself->nice = value;
- debug_printf ("Set nice to %d", myself->nice);
return 0;
}
extern "C" int
getpriority (int which, id_t who)
{
- /* TODO: Support PRIO_PGRP and PRIO_USER. */
- if (which != PRIO_PROCESS || (who != 0 && (pid_t) who != myself->pid))
+ int nice = NZERO * 2; /* Illegal value */
+
+ switch (which)
{
+ case PRIO_PROCESS:
+ if (!who)
+ who = myself->pid;
+ if ((pid_t) who == myself->pid)
+ return myself->nice;
+ break;
+ case PRIO_PGRP:
+ if (!who)
+ who = myself->pgid;
+ break;
+ case PRIO_USER:
+ if (!who)
+ who = myself->uid;
+ break;
+ default:
set_errno (EINVAL);
return -1;
}
- return myself->nice;
+ winpids pids ((DWORD) 0);
+ for (DWORD i = 0; i < pids.npids; ++i)
+ {
+ _pinfo *p = pids[i];
+ if (p)
+ switch (which)
+ {
+ case PRIO_PROCESS:
+ if ((pid_t) who == p->pid)
+ {
+ nice = p->nice;
+ goto out;
+ }
+ break;
+ case PRIO_PGRP:
+ if ((pid_t) who == p->pgid && p->nice < nice)
+ nice = p->nice;
+ break;
+ case PRIO_USER:
+ if ((__uid32_t) who == p->uid && p->nice < nice)
+ nice = p->nice;
+ break;
+ }
+ }
+out:
+ pids.reset ();
+ if (nice == NZERO * 2)
+ {
+ set_errno (ESRCH);
+ return -1;
+ }
+ return nice;
}
extern "C" int