Cygwin: setpriority, sched_setparam: fail if Windows sets a lower priority
Windows silently sets a lower priority than requested if the new priority requires administrator privileges. Revert to previous priority and fail with EACCES or EPERM in this case. Signed-off-by: Christian Franke <christian.franke@t-online.de>
This commit is contained in:
parent
46d1e63c76
commit
153b51ee08
5 changed files with 38 additions and 3 deletions
|
@ -46,6 +46,7 @@ is_alt_numpad_event (PINPUT_RECORD pirec)
|
|||
|
||||
int winprio_to_nice (DWORD);
|
||||
DWORD nice_to_winprio (int &);
|
||||
bool set_and_check_winprio (HANDLE proc, DWORD prio);
|
||||
|
||||
bool create_pipe (PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD);
|
||||
|
||||
|
|
|
@ -183,6 +183,35 @@ nice_to_winprio (int &nice)
|
|||
return prio;
|
||||
}
|
||||
|
||||
/* Set Win32 priority or return false on failure. Also return
|
||||
false and revert to the original priority if a different (lower)
|
||||
priority is set instead. */
|
||||
bool
|
||||
set_and_check_winprio (HANDLE proc, DWORD prio)
|
||||
{
|
||||
DWORD prev_prio = GetPriorityClass (proc);
|
||||
if (prev_prio == prio)
|
||||
return true;
|
||||
|
||||
if (!SetPriorityClass (proc, prio))
|
||||
return false;
|
||||
|
||||
/* Windows silently sets a lower priority (HIGH_PRIORITY_CLASS) if
|
||||
the new priority (REALTIME_PRIORITY_CLASS) requires administrator
|
||||
privileges. */
|
||||
DWORD curr_prio = GetPriorityClass (proc);
|
||||
if (curr_prio != prio)
|
||||
{
|
||||
debug_printf ("Failed to set priority 0x%x, revert from 0x%x to 0x%x",
|
||||
prio, curr_prio, prev_prio);
|
||||
SetPriorityClass (proc, prev_prio);
|
||||
return false;
|
||||
}
|
||||
|
||||
debug_printf ("Changed priority from 0x%x to 0x%x", prev_prio, curr_prio);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Minimal overlapped pipe I/O implementation for signal and commune stuff. */
|
||||
|
||||
BOOL
|
||||
|
|
|
@ -43,3 +43,8 @@ What changed:
|
|||
|
||||
- Now using AVX/AVX2/AVX-512 instructions in signal handler does not
|
||||
break their context.
|
||||
|
||||
- nice(2), setpriority(2) and sched_setparam(2) now fail with EACCES
|
||||
or EPERM if Windows would silently set a lower priority
|
||||
(HIGH_PRIORITY_CLASS instead of REALTIME_PRIORITY_CLASS) due to
|
||||
missing administrator privileges.
|
||||
|
|
|
@ -266,7 +266,7 @@ sched_setparam (pid_t pid, const struct sched_param *param)
|
|||
set_errno (ESRCH);
|
||||
return -1;
|
||||
}
|
||||
if (!SetPriorityClass (process, pclass))
|
||||
if (!set_and_check_winprio (process, pclass))
|
||||
{
|
||||
CloseHandle (process);
|
||||
set_errno (EPERM);
|
||||
|
|
|
@ -3826,7 +3826,7 @@ setpriority (int which, id_t who, int value)
|
|||
who = myself->pid;
|
||||
if ((pid_t) who == myself->pid)
|
||||
{
|
||||
if (!SetPriorityClass (GetCurrentProcess (), prio))
|
||||
if (!set_and_check_winprio (GetCurrentProcess (), prio))
|
||||
{
|
||||
set_errno (EACCES);
|
||||
return -1;
|
||||
|
@ -3875,7 +3875,7 @@ setpriority (int which, id_t who, int value)
|
|||
error = EPERM;
|
||||
else
|
||||
{
|
||||
if (!SetPriorityClass (proc_h, prio))
|
||||
if (!set_and_check_winprio (proc_h, prio))
|
||||
error = EACCES;
|
||||
else
|
||||
p->nice = value;
|
||||
|
|
Loading…
Add table
Reference in a new issue