1 /*
2  * nice() for uClibc
3  *
4  * Copyright (C) 2005 by Manuel Novoa III <mjn3@codepoet.org>
5  * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
6  *
7  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
8  */
9 
10 #include <sys/syscall.h>
11 #include <unistd.h>
12 #include <sys/resource.h>
13 
14 
15 #ifdef __NR_nice
16 
17 # define __NR___syscall_nice __NR_nice
_syscall1(int,__syscall_nice,int,incr)18 static __inline__ _syscall1(int, __syscall_nice, int, incr)
19 
20 #else
21 
22 # include <limits.h>
23 
24 
25 static __inline__ int int_add_no_wrap(int a, int b)
26 {
27 	if (b < 0) {
28 		if (a < INT_MIN - b)
29 			return INT_MIN;
30 	} else {
31 		if (a > INT_MAX - b)
32 			return INT_MAX;
33 	}
34 
35 	return a + b;
36 }
37 
38 static __inline__ int __syscall_nice(int incr)
39 {
40 	int old_priority;
41 # if 1
42 	/* This should never fail. */
43 	old_priority = getpriority(PRIO_PROCESS, 0);
44 # else
45 	/* But if you want to be paranoid... */
46 	int old_errno;
47 
48 	old_errno = errno;
49 	__set_errno(0);
50 	old_priority = getpriority(PRIO_PROCESS, 0);
51 	if ((old_priority == -1) && errno) {
52 		return -1;
53 	}
54 	__set_errno(old_errno);
55 # endif
56 
57 	if (setpriority(PRIO_PROCESS, 0, int_add_no_wrap(old_priority, incr))) {
58 		__set_errno(EPERM);	/* SUSv3 mandates EPERM for nice failure. */
59 		return -1;
60 	}
61 
62 	return 0;
63 }
64 
65 #endif
66 
67 int nice(int incr)
68 {
69 	if (__syscall_nice(incr)) {
70 		return -1;
71 	}
72 
73 	return getpriority(PRIO_PROCESS, 0);
74 }
75