library: Return -errno not print messages

A library should generally return an error value, rather than
printing to stderr a message. procps_loadavg() had a few things
to change:

It had a global buffer, but we don't call this function over and
over except in tload. It also did had two macros where a plain
fopen() would do the job nicely.

This removed the macro FILE_TO_BUF which was used everywhere in oldlib
but only for loadavg in newlib.

This library change will set us up to fix tload.
This commit is contained in:
Craig Small 2022-05-31 21:32:03 +10:00
parent 0ab507fdb1
commit 8fcd14de18

View File

@ -36,40 +36,7 @@
#include "procps-private.h" #include "procps-private.h"
#define BAD_OPEN_MESSAGE \
"Error: /proc must be mounted\n" \
" To mount /proc at boot you need an /etc/fstab line like:\n" \
" proc /proc proc defaults\n" \
" In the meantime, run \"mount proc /proc -t proc\"\n"
#define LOADAVG_FILE "/proc/loadavg" #define LOADAVG_FILE "/proc/loadavg"
static int loadavg_fd = -1;
// As of 2.6.24 /proc/meminfo seems to need 888 on 64-bit,
// and would need 1258 if the obsolete fields were there.
// As of 3.13 /proc/vmstat needs 2623,
// and /proc/stat needs 3076.
static __thread char buf[8192];
/* This macro opens filename only if necessary and seeks to 0 so
* that successive calls to the functions are more efficient.
* It also reads the current contents of the file into the global buf.
*/
#define FILE_TO_BUF(filename, fd) do{ \
static __thread int local_n; \
if (fd == -1 && (fd = open(filename, O_RDONLY)) == -1) { \
fputs(BAD_OPEN_MESSAGE, stderr); \
fflush(NULL); \
_exit(102); \
} \
lseek(fd, 0L, SEEK_SET); \
if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) { \
perror(filename); \
fflush(NULL); \
_exit(103); \
} \
buf[local_n] = '\0'; \
}while(0)
/* evals 'x' twice */ /* evals 'x' twice */
#define SET_IF_DESIRED(x,y) do{ if(x) *(x) = (y); }while(0) #define SET_IF_DESIRED(x,y) do{ if(x) *(x) = (y); }while(0)
@ -125,12 +92,15 @@ PROCPS_EXPORT int procps_loadavg(
{ {
double avg_1=0, avg_5=0, avg_15=0; double avg_1=0, avg_5=0, avg_15=0;
locale_t tmplocale; locale_t tmplocale;
int retval=0; int retval;
FILE *fp;
if ((fp = fopen(LOADAVG_FILE, "r")) == NULL)
return -errno;
FILE_TO_BUF(LOADAVG_FILE,loadavg_fd);
tmplocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); tmplocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
uselocale(tmplocale); uselocale(tmplocale);
if (sscanf(buf, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3) if (fscanf(fp, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3)
retval = -ERANGE; retval = -ERANGE;
uselocale(LC_GLOBAL_LOCALE); uselocale(LC_GLOBAL_LOCALE);