diff --git a/proc/libprocps.sym b/proc/libprocps.sym index 3907f5a8..de47789c 100644 --- a/proc/libprocps.sym +++ b/proc/libprocps.sym @@ -57,8 +57,10 @@ global: strtosig; tty_to_dev; unix_print_signals; - uptime; user_from_uid; + uptime; + sprint_uptime; + sprint_uptime_short; procps_linux_version; procps_meminfo_new; procps_meminfo_read; diff --git a/proc/sysinfo.c b/proc/sysinfo.c index b0af54f0..bbd11194 100644 --- a/proc/sysinfo.c +++ b/proc/sysinfo.c @@ -47,8 +47,6 @@ long page_bytes; /* this architecture's page size */ #define STAT_FILE "/proc/stat" static int stat_fd = -1; -#define UPTIME_FILE "/proc/uptime" -static int uptime_fd = -1; #define LOADAVG_FILE "/proc/loadavg" static int loadavg_fd = -1; #define MEMINFO_FILE "/proc/meminfo" @@ -91,25 +89,6 @@ static char buf[8192]; #define MIN(x,y) ((x) < (y) ? (x) : (y)) /***********************************************************************/ -int uptime(double *restrict uptime_secs, double *restrict idle_secs) { - double up=0, idle=0; - char *savelocale; - - FILE_TO_BUF(UPTIME_FILE,uptime_fd); - savelocale = strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC,"C"); - if (sscanf(buf, "%lf %lf", &up, &idle) < 2) { - setlocale(LC_NUMERIC,savelocale); - free(savelocale); - fputs("bad data in " UPTIME_FILE "\n", stderr); - return 0; - } - setlocale(LC_NUMERIC,savelocale); - free(savelocale); - SET_IF_DESIRED(uptime_secs, up); - SET_IF_DESIRED(idle_secs, idle); - return up; /* assume never be zero seconds in practice */ -} unsigned long getbtime(void) { static unsigned long btime = 0; @@ -176,6 +155,7 @@ unsigned long getbtime(void) { unsigned long long Hertz; +#if 0 static void old_Hertz_hack(void){ unsigned long long user_j, nice_j, sys_j, other_j, wait_j, hirq_j, sirq_j, stol_j; /* jiffies (clock ticks) */ double up_1, up_2, seconds; @@ -235,7 +215,7 @@ static void old_Hertz_hack(void){ fprintf(stderr, "Unknown HZ value! (%d) Assume %Ld.\n", h, Hertz); } } - +#endif // same as: euid != uid || egid != gid #ifndef AT_SECURE #define AT_SECURE 23 // secure mode boolean (true if setuid, etc.) @@ -287,15 +267,8 @@ static void init_libproc(void){ // fputs("2.4+ kernel w/o ELF notes? -- report this\n", stderr); } #endif /* __linux __ */ -#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) - /* On FreeBSD the Hertz hack is unrelaible, there is no ELF note and - * Hertz isn't defined in asm/params.h - * See Debian Bug #460331 - */ Hertz = 100; return; -#endif /* __FreeBSD__ */ - old_Hertz_hack(); } #if 0 diff --git a/proc/uptime.c b/proc/uptime.c new file mode 100644 index 00000000..cdc207fb --- /dev/null +++ b/proc/uptime.c @@ -0,0 +1,203 @@ +/* + * uptime - uptime related functions - part of procps + * + * Copyright (C) 1992-1998 Michael K. Johnson + * Copyright (C) ???? Larry Greenfield + * Copyright (C) 1993 J. Cowley + * Copyright (C) 1998-2003 Albert Cahalan + * Copyright (C) 2015 Craig Small + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "procps-private.h" + +#define UPTIME_FILE "/proc/uptime" + +static __thread char upbuf[128]; +static __thread char shortbuf[128]; + +static int count_users(void) +{ + int numuser = 0; + struct utmp *ut; + + setutent(); + while ((ut = getutent())) { + if ((ut->ut_type == USER_PROCESS) && (ut->ut_name[0] != '\0')) + numuser++; + } + endutent(); + + return numuser; +} +/* + * uptime: + * + * Find the uptime and idle time of the system. + * These numbers are found in /proc/uptime + * Unlike other procps functions this closes the file each time + * Either uptime_secs or idle_secs can be null + * + * Returns: uptime_secs on success and <0 on failure + */ +PROCPS_EXPORT int uptime(double *restrict uptime_secs, double *restrict idle_secs) +{ + double up=0, idle=0; + char *savelocale; + char buf[256]; + FILE *fp; + + if ((fp = fopen(UPTIME_FILE, "r")) == NULL) + return -errno; + savelocale = strdup(setlocale(LC_NUMERIC, NULL)); + setlocale(LC_NUMERIC, "C"); + if (fscanf(fp, "%lf %lf", &up, &idle) < 2) { + setlocale(LC_NUMERIC, savelocale); + free(savelocale); + fclose(fp); + return -ERANGE; + } + fclose(fp); + setlocale(LC_NUMERIC, savelocale); + free(savelocale); + if (uptime_secs) + *uptime_secs = up; + if (idle_secs) + *idle_secs = idle; + return up; +} + +/* + * sprint_uptime: + * + * Print current time in nice format + * + * Returns a statically allocated upbuf or NULL on error + */ +PROCPS_EXPORT char *sprint_uptime(void) +{ + int upminutes, uphours, updays, users; + int pos; + time_t realseconds; + struct tm *realtime; + double uptime_secs, idle_secs; + double av1, av5, av15; + + if (time(&realseconds) < 0) + return NULL; + realtime = localtime(&realseconds); + pos = sprintf(upbuf, " %02d:%02d:%02d ", + realtime->tm_hour, realtime->tm_min, realtime->tm_sec); + if (uptime(&uptime_secs, &idle_secs) < 0) + return NULL; + + updays = ((int) uptime_secs / (60*60*24)); + uphours = ((int) uptime_secs / (60*24)) % 24; + upminutes = ((int) uptime_secs / (60)) % 60; + + pos = sprintf(upbuf, "%02d:%02d:%02d up %d %s, ", + realtime->tm_hour, realtime->tm_min, realtime->tm_sec, + updays, (updays != 1) ? "days" : "day"); + if (uphours) + pos += sprintf(upbuf + pos, "%2d:%02d, ", uphours, upminutes); + else + pos += sprintf(upbuf + pos, "%d min, ", uphours, upminutes); + + users = count_users(); + loadavg(&av1, &av5, &av15); + + pos += sprintf(upbuf + pos, "%2d user%s, load average: %.2f, %.2f, %.2f", + users, users == 1 ? "" : "s", + av1, av5, av15); + + +} + +PROCPS_EXPORT char *sprint_uptime_short(void) +{ + int updecades, upyears, upweeks, updays, uphours, upminutes; + int pos = 3; + int comma = 0; + time_t realseconds; + struct tm *realtime; + double uptime_secs, idle_secs; + + if (uptime(&uptime_secs, &idle_secs) < 0) + return NULL; + + updecades = (int) uptime_secs / (60*60*24*365*10); + upyears = ((int) uptime_secs / (60*60*24*365)) % 10; + upweeks = ((int) uptime_secs / (60*60*24*7)) % 52; + updays = ((int) uptime_secs / (60*60*24)) % 7; + uphours = ((int) uptime_secs / (60*24)) % 24; + upminutes = ((int) uptime_secs / (60)) % 60; + + strcat(shortbuf, "up "); + + if (updecades) { + pos += sprintf(shortbuf + pos, "%d %s", + updecades, updecades > 1 ? "decades" : "decade"); + comma +1; + } + + if (upyears) { + pos += sprintf(shortbuf + pos, "%s%d %s", + comma > 0 ? ", " : "", upyears, + upyears > 1 ? "years" : "year"); + comma += 1; + } + + if (upweeks) { + pos += sprintf(shortbuf + pos, "%s%d %s", + comma > 0 ? ", " : "", upweeks, + upweeks > 1 ? "weeks" : "week"); + comma += 1; + } + + if (updays) { + pos += sprintf(shortbuf + pos, "%s%d %s", + comma > 0 ? ", " : "", updays, + updays > 1 ? "days" : "day"); + comma += 1; + } + + if (uphours) { + pos += sprintf(shortbuf + pos, "%s%d %s", + comma > 0 ? ", " : "", uphours, + uphours > 1 ? "hours" : "hour"); + comma += 1; + } + + if (upminutes) { + pos += sprintf(shortbuf + pos, "%s%d %s", + comma > 0 ? ", " : "", upminutes, + upminutes > 1 ? "minutes" : "minute"); + comma += 1; + } + return shortbuf; +} + diff --git a/proc/uptime.h b/proc/uptime.h new file mode 100644 index 00000000..1288dccb --- /dev/null +++ b/proc/uptime.h @@ -0,0 +1,38 @@ +/* + * uptime - uptime related functions - part of procps + * + * Copyright (C) 1992-1998 Michael K. Johnson + * Copyright (C) ???? Larry Greenfield + * Copyright (C) 1993 J. Cowley + * Copyright (C) 1998-2003 Albert Cahalan + * Copyright (C) 2015 Craig Small + * + * This library is free software; you can redistribute it and/or + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef PROC_UPTIME_H +#define PROC_UPTIME_H + +#include + +__BEGIN_DECLS + +int uptime(double *uptime_secs, double *idle_secs); +char *sprint_uptime(void); +char *sprint_uptime_short(void); + +__END_DECLS + +#endif diff --git a/proc/whattime.c b/proc/whattime.c deleted file mode 100644 index eb345fb1..00000000 --- a/proc/whattime.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * This is a trivial uptime program. I hereby release this program - * into the public domain. I disclaim any responsibility for this - * program --- use it at your own risk. (as if there were any.. ;-) - * -michaelkjohnson (johnsonm@sunsite.unc.edu) - * - * Modified by Larry Greenfield to give a more traditional output, - * count users, etc. (greenfie@gauss.rutgers.edu) - * - * Modified by mkj again to fix a few tiny buglies. - * - * Modified by J. Cowley to add printing the uptime message to a - * string (for top) and to optimize file handling. 19 Mar 1993. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "whattime.h" -#include "sysinfo.h" - -static char buf[128]; -static double av[3]; - -char *sprint_uptime(int human_readable) { - struct utmp *utmpstruct; - int upminutes, uphours, updays, upweeks, upyears, updecades; - int pos; - int comma; - struct tm *realtime; - time_t realseconds; - int numuser; - double uptime_secs, idle_secs; - -/* first get the current time */ - - if (!human_readable) { - time(&realseconds); - realtime = localtime(&realseconds); - pos = sprintf(buf, " %02d:%02d:%02d ", - realtime->tm_hour, realtime->tm_min, realtime->tm_sec); - } else { - pos = 0; - } - -/* read and calculate the amount of uptime */ - - uptime(&uptime_secs, &idle_secs); - - if (human_readable) { - updecades = (int) uptime_secs / (60*60*24*365*10); - upyears = ((int) uptime_secs / (60*60*24*365)) % 10; - upweeks = ((int) uptime_secs / (60*60*24*7)) % 52; - updays = ((int) uptime_secs / (60*60*24)) % 7; - } - else - updays = (int) uptime_secs / (60*60*24); - - strcat (buf, "up "); - pos += 3; - - if (!human_readable) { - if (updays) - pos += sprintf(buf + pos, "%d day%s, ", updays, (updays != 1) ? "s" : ""); - } - - upminutes = (int) uptime_secs / 60; - uphours = upminutes / 60; - uphours = uphours % 24; - upminutes = upminutes % 60; - - if (!human_readable) { - if(uphours) - pos += sprintf(buf + pos, "%2d:%02d, ", uphours, upminutes); - else - pos += sprintf(buf + pos, "%d min, ", upminutes); - -/* count the number of users */ - - numuser = 0; - setutent(); - while ((utmpstruct = getutent())) { - if ((utmpstruct->ut_type == USER_PROCESS) && - (utmpstruct->ut_name[0] != '\0')) - numuser++; - } - endutent(); - - pos += sprintf(buf + pos, "%2d user%s, ", numuser, numuser == 1 ? "" : "s"); - - loadavg(&av[0], &av[1], &av[2]); - - pos += sprintf(buf + pos, " load average: %.2f, %.2f, %.2f", - av[0], av[1], av[2]); - } - - if (human_readable) { - comma = 0; - - if (updecades) { - pos += sprintf(buf + pos, "%d %s", updecades, - updecades > 1 ? "decades" : "decade"); - comma += 1; - } - - if (upyears) { - pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", upyears, - upyears > 1 ? "years" : "year"); - comma += 1; - } - - if (upweeks) { - pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", upweeks, - upweeks > 1 ? "weeks" : "week"); - comma += 1; - } - - if (updays) { - pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", updays, - updays > 1 ? "days" : "day"); - comma += 1; - } - - if (uphours) { - pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", uphours, - uphours > 1 ? "hours" : "hour"); - comma += 1; - } - - if (upminutes) { - pos += sprintf(buf + pos, "%s%d %s", comma > 0 ? ", " : "", upminutes, - upminutes > 1 ? "minutes" : "minute"); - comma += 1; - } - } - - return buf; -} - -void print_uptime(int human_readable) { - printf("%s\n", sprint_uptime(human_readable)); -} diff --git a/proc/whattime.h b/proc/whattime.h deleted file mode 100644 index f0a16e93..00000000 --- a/proc/whattime.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PROC_WHATTIME_H -#define PROC_WHATTIME_H - -#include - -__BEGIN_DECLS - -extern void print_uptime(int human_readable); -extern char *sprint_uptime(int human_readable); - -__END_DECLS - -#endif diff --git a/top/top.c b/top/top.c index 273c4a54..e532e299 100644 --- a/top/top.c +++ b/top/top.c @@ -56,7 +56,7 @@ #include "../proc/sysinfo.h" #include "../proc/version.h" #include "../proc/wchan.h" -#include "../proc/whattime.h" +#include "../proc/uptime.h" #include "top.h" #include "top_nls.h" @@ -5129,10 +5129,10 @@ static void summary_show (void) { // Display Uptime and Loadavg if (isROOM(View_LOADAV, 1)) { if (!Rc.mode_altscr) - show_special(0, fmtmk(LOADAV_line, Myname, sprint_uptime(0))); + show_special(0, fmtmk(LOADAV_line, Myname, sprint_uptime())); else show_special(0, fmtmk(CHKw(w, Show_TASKON)? LOADAV_line_alt : LOADAV_line - , w->grpname, sprint_uptime(0))); + , w->grpname, sprint_uptime())); Msg_row += 1; } // end: View_LOADAV diff --git a/uptime.c b/uptime.c index 91275ca8..b8a0ab4b 100644 --- a/uptime.c +++ b/uptime.c @@ -28,7 +28,7 @@ #include "fileutils.h" #include "nls.h" #include "proc/sysinfo.h" -#include "proc/whattime.h" +#include #include "proc/version.h" static void print_uptime_since() @@ -104,6 +104,9 @@ int main(int argc, char **argv) usage(stderr); } - print_uptime(p); + if (p) + printf("%s\n", sprint_uptime()); + else + printf("%s\n", sprint_uptime_short()); return EXIT_SUCCESS; } diff --git a/w.c b/w.c index 4c8a6193..7870b813 100644 --- a/w.c +++ b/w.c @@ -32,7 +32,7 @@ #include "proc/readproc.h" #include "proc/sysinfo.h" #include "proc/version.h" -#include "proc/whattime.h" +#include #include #include @@ -584,7 +584,7 @@ int main(int argc, char **argv) if (header) { /* print uptime and headers */ - print_uptime(0); + printf("%s\n", sprint_uptime()); /* Translation Hint: Following five uppercase messages are * headers. Try to keep alignment intact. */ printf(_("%-*s TTY "), userlen, _("USER"));