aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-02-15 23:43:36 +0000
committerUlrich Drepper <drepper@redhat.com>2009-02-15 23:43:36 +0000
commitf43b4be6556daf9d406bca5d3cfe4e6722ef02c7 (patch)
tree52b943c631f440ba2ade379ce27119ff6ed87991
parent4c869eb67e0852e8026c9975bca5239adf6956d0 (diff)
downloadglibc-f43b4be6556daf9d406bca5d3cfe4e6722ef02c7.zip
glibc-f43b4be6556daf9d406bca5d3cfe4e6722ef02c7.tar.gz
glibc-f43b4be6556daf9d406bca5d3cfe4e6722ef02c7.tar.bz2
* sysdeps/unix/sysv/linux/getsysstats.c (next_line): New function.
(GET_NPROCS_PARSER): Change parameters and use next_line. (__get_nprocs): Rewrite to not use stdio routines. * sysdeps/unix/sysv/linux/sparc/getsysstats.c (GET_NPROCS_PARSER): Change parameters and use next_line.
-rw-r--r--ChangeLog8
-rw-r--r--sysdeps/unix/sysv/linux/getsysstats.c85
-rw-r--r--sysdeps/unix/sysv/linux/sparc/getsysstats.c9
3 files changed, 79 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 9293d21..57e3777 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-02-15 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/getsysstats.c (next_line): New function.
+ (GET_NPROCS_PARSER): Change parameters and use next_line.
+ (__get_nprocs): Rewrite to not use stdio routines.
+ * sysdeps/unix/sysv/linux/sparc/getsysstats.c (GET_NPROCS_PARSER):
+ Change parameters and use next_line.
+
2009-02-13 Ulrich Drepper <drepper@redhat.com>
[BZ #5381]
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index 6d4c9c0..28f52c0 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -1,5 +1,5 @@
/* Determine various system internal values, Linux version.
- Copyright (C) 1996-2001, 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1996-2003, 2006, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -49,10 +49,13 @@
But not all systems have support for the /proc filesystem. If it
is not available we simply return 1 since there is no way. */
+#include <not-cancel.h>
+
+
/* Other architectures use different formats for /proc/cpuinfo. This
provides a hook for alternative parsers. */
#ifndef GET_NPROCS_PARSER
-# define GET_NPROCS_PARSER(FP, BUFFER, RESULT) \
+# define GET_NPROCS_PARSER(FD, BUFFER, CP, RE, BUFFER_END, RESULT) \
do \
{ \
(RESULT) = 0; \
@@ -60,45 +63,89 @@
"processor". We don't have to fear extremely long lines since \
the kernel will not generate them. 8192 bytes are really \
enough. */ \
- while (fgets_unlocked (BUFFER, sizeof (BUFFER), FP) != NULL) \
- if (strncmp (BUFFER, "processor", 9) == 0) \
+ char *l; \
+ while ((l = next_line (FD, BUFFER, &CP, &RE, BUFFER_END)) != NULL) \
+ if (strncmp (l, "processor", 9) == 0) \
++(RESULT); \
} \
while (0)
#endif
+static char *
+next_line (int fd, char *const buffer, char **cp, char **re,
+ char *const buffer_end)
+{
+ char *res = *cp;
+ char *nl = memchr (*cp, '\n', *re - *cp);
+ if (nl == NULL)
+ {
+ if (*cp != buffer)
+ {
+ if (*re == buffer_end)
+ {
+ memmove (buffer, *cp, *re - *cp);
+ *re = buffer + (*re - *cp);
+ *cp = buffer;
+
+ ssize_t n = read_not_cancel (fd, *re, buffer_end - *re);
+ if (n < 0)
+ return NULL;
+
+ *re += n;
+ }
+
+ res = *cp;
+ nl = memchr (*cp, '\n', *re - *cp);
+ }
+
+ if (nl == NULL)
+ nl = *re - 1;
+ }
+
+ *cp = nl + 1;
+ assert (*cp <= *re);
+
+ return res == *re ? NULL : res;
+}
+
+
int
__get_nprocs ()
{
/* XXX Here will come a test for the new system call. */
char buffer[8192];
+ char *const buffer_end = buffer + sizeof (buffer);
+ char *cp = buffer_end;
+ char *re = buffer_end;
int result = 1;
+#ifdef O_CLOEXEC
+ const int flags = O_RDONLY | O_CLOEXEC;
+#else
+ const int flags = O_RDONLY;
+#endif
/* The /proc/stat format is more uniform, use it by default. */
- FILE *fp = fopen ("/proc/stat", "rc");
- if (fp != NULL)
+ int fd = open_not_cancel_2 ("/proc/stat", flags);
+ if (fd != -1)
{
- /* No threads use this stream. */
- __fsetlocking (fp, FSETLOCKING_BYCALLER);
-
result = 0;
- while (fgets_unlocked (buffer, sizeof (buffer), fp) != NULL)
- if (strncmp (buffer, "cpu", 3) == 0 && isdigit (buffer[3]))
+
+ char *l;
+ while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL)
+ if (strncmp (l, "cpu", 3) == 0 && isdigit (l[3]))
++result;
- fclose (fp);
+ close_not_cancel_no_status (fd);
}
else
{
- fp = fopen ("/proc/cpuinfo", "rc");
- if (fp != NULL)
+ fd = open_not_cancel_2 ("/proc/cpuinfo", flags);
+ if (fd != -1)
{
- /* No threads use this stream. */
- __fsetlocking (fp, FSETLOCKING_BYCALLER);
- GET_NPROCS_PARSER (fp, buffer, result);
- fclose (fp);
+ GET_NPROCS_PARSER (fd, buffer, cp, re, buffer_end, result);
+ close_not_cancel_no_status (fd);
}
}
@@ -141,7 +188,7 @@ __get_nprocs_conf ()
#ifdef GET_NPROCS_CONF_PARSER
/* If we haven't found an appropriate entry return 1. */
- FILE *fp = fopen ("/proc/cpuinfo", "rc");
+ FILE *fp = fopen ("/proc/cpuinfo", "rce");
if (fp != NULL)
{
char buffer[8192];
diff --git a/sysdeps/unix/sysv/linux/sparc/getsysstats.c b/sysdeps/unix/sysv/linux/sparc/getsysstats.c
index f064b37..e96a8e5 100644
--- a/sysdeps/unix/sysv/linux/sparc/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/sparc/getsysstats.c
@@ -1,5 +1,5 @@
/* Determine various system internal values, Linux/Sparc version.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Schwab <schwab@suse.de> and
Jakub Jelinek <jj@ultra.linux.cz>
@@ -21,7 +21,7 @@
/* We need to define a special parser for /proc/cpuinfo. */
-#define GET_NPROCS_PARSER(FP, BUFFER, RESULT) \
+#define GET_NPROCS_PARSER(FD, BUFFER, CP, RE, BUFFER_END, RESULT) \
do \
{ \
(RESULT) = 0; \
@@ -29,8 +29,9 @@
active cpus. We don't have to fear extremely long lines since \
the kernel will not generate them. 8192 bytes are really \
enough. */ \
- while (fgets_unlocked (BUFFER, sizeof (BUFFER), FP) != NULL) \
- if (sscanf (BUFFER, "ncpus active : %d", &(RESULT)) == 1) \
+ char *l; \
+ while ((l = next_line (FD, BUFFER, &CP, &RE, BUFFER_END)) != NULL) \
+ if (sscanf (l, "ncpus active : %d", &(RESULT)) == 1) \
break; \
} \
while (0)