glibc: Backport hotfixes from RHEL6.
[people/teissler/ipfire-2.x.git] / src / patches / glibc / glibc-rh952422.patch
1 diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
2 index af454b6..249bd19 100644
3 --- a/sysdeps/unix/sysv/linux/getsysstats.c
4 +++ b/sysdeps/unix/sysv/linux/getsysstats.c
5 @@ -35,6 +34,7 @@
6
7 #include <atomic.h>
8 #include <not-cancel.h>
9 +#include <kernel-features.h>
10
11
12 /* How we can determine the number of available processors depends on
13 @@ -49,8 +49,6 @@
14 But not all systems have support for the /proc filesystem. If it
15 is not available we simply return 1 since there is no way. */
16
17 -#include <not-cancel.h>
18 -
19
20 /* Other architectures use different formats for /proc/cpuinfo. This
21 provides a hook for alternative parsers. */
22 @@ -128,6 +126,15 @@ next_line (int fd, char *const buffer, char **cp, char **re,
23 int
24 __get_nprocs ()
25 {
26 + static int cached_result;
27 + static time_t timestamp;
28 +
29 + time_t now = time (NULL);
30 + time_t prev = timestamp;
31 + atomic_read_barrier ();
32 + if (now == prev)
33 + return cached_result;
34 +
35 /* XXX Here will come a test for the new system call. */
36
37 const size_t buffer_size = __libc_use_alloca (8192) ? 8192 : 512;
38 @@ -135,20 +142,65 @@ __get_nprocs ()
39 char *buffer_end = buffer + buffer_size;
40 char *cp = buffer_end;
41 char *re = buffer_end;
42 - int result = 1;
43
44 #ifdef O_CLOEXEC
45 const int flags = O_RDONLY | O_CLOEXEC;
46 #else
47 const int flags = O_RDONLY;
48 #endif
49 + int fd = open_not_cancel_2 ("/sys/devices/system/cpu/online", flags);
50 + char *l;
51 + int result = 0;
52 + if (fd != -1)
53 + {
54 + l = next_line (fd, buffer, &cp, &re, buffer_end);
55 + if (l != NULL)
56 + do
57 + {
58 + char *endp;
59 + unsigned long int n = strtoul (l, &endp, 10);
60 + if (l == endp)
61 + {
62 + result = 0;
63 + break;
64 + }
65 +
66 + unsigned long int m = n;
67 + if (*endp == '-')
68 + {
69 + l = endp + 1;
70 + m = strtoul (l, &endp, 10);
71 + if (l == endp)
72 + {
73 + result = 0;
74 + break;
75 + }
76 + }
77 +
78 + result += m - n + 1;
79 +
80 + l = endp;
81 + while (l < re && isspace (*l))
82 + ++l;
83 + }
84 + while (l < re);
85 +
86 + close_not_cancel_no_status (fd);
87 +
88 + if (result > 0)
89 + goto out;
90 + }
91 +
92 + cp = buffer_end;
93 + re = buffer_end;
94 + result = 1;
95 +
96 /* The /proc/stat format is more uniform, use it by default. */
97 - int fd = open_not_cancel_2 ("/proc/stat", flags);
98 + fd = open_not_cancel_2 ("/proc/stat", flags);
99 if (fd != -1)
100 {
101 result = 0;
102
103 - char *l;
104 while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL)
105 /* The current format of /proc/stat has all the cpu* entries
106 at the front. We assume here that stays this way. */
107 @@ -169,6 +221,11 @@ __get_nprocs ()
108 }
109 }
110
111 + out:
112 + cached_result = result;
113 + atomic_write_barrier ();
114 + timestamp = now;
115 +
116 return result;
117 }
118 weak_alias (__get_nprocs, get_nprocs)
119 @@ -236,7 +293,7 @@ phys_pages_info (const char *format)
120 long int result = -1;
121
122 /* If we haven't found an appropriate entry return 1. */
123 - FILE *fp = fopen ("/proc/meminfo", "rc");
124 + FILE *fp = fopen ("/proc/meminfo", "rce");
125 if (fp != NULL)
126 {
127 /* No threads use this stream. */