LCOV - code coverage report
Current view: top level - src - uptime.c (source / functions) Hit Total Coverage
Test: coreutils.info Lines: 70 81 86.4 %
Date: 2018-01-30 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* GNU's uptime.
       2             :    Copyright (C) 1992-2002, 2004-2007 Free Software Foundation, Inc.
       3             : 
       4             :    This program is free software: you can redistribute it and/or modify
       5             :    it under the terms of the GNU General Public License as published by
       6             :    the Free Software Foundation, either version 3 of the License, or
       7             :    (at your option) any later version.
       8             : 
       9             :    This program is distributed in the hope that it will be useful,
      10             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :    GNU General Public License for more details.
      13             : 
      14             :    You should have received a copy of the GNU General Public License
      15             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      16             : 
      17             : /* Created by hacking who.c by Kaveh Ghazi ghazi@caip.rutgers.edu.  */
      18             : 
      19             : #include <config.h>
      20             : #include <getopt.h>
      21             : #include <stdio.h>
      22             : 
      23             : #include <sys/types.h>
      24             : #include "system.h"
      25             : 
      26             : #if HAVE_SYSCTL && HAVE_SYS_SYSCTL_H
      27             : # include <sys/sysctl.h>
      28             : #endif
      29             : 
      30             : #if HAVE_OS_H
      31             : # include <OS.h>
      32             : #endif
      33             : 
      34             : #include "c-strtod.h"
      35             : #include "error.h"
      36             : #include "long-options.h"
      37             : #include "quote.h"
      38             : #include "readutmp.h"
      39             : 
      40             : /* The official name of this program (e.g., no `g' prefix).  */
      41             : #define PROGRAM_NAME "uptime"
      42             : 
      43             : #define AUTHORS "Joseph Arceneaux", "David MacKenzie", "Kaveh Ghazi"
      44             : 
      45             : int getloadavg ();
      46             : 
      47             : /* The name this program was run with. */
      48             : char *program_name;
      49             : 
      50             : static void
      51          10 : print_uptime (size_t n, const STRUCT_UTMP *this)
      52             : {
      53          10 :   size_t entries = 0;
      54          10 :   time_t boot_time = 0;
      55             :   time_t time_now;
      56          10 :   time_t uptime = 0;
      57             :   long int updays;
      58             :   int uphours;
      59             :   int upmins;
      60             :   struct tm *tmn;
      61             :   double avg[3];
      62             :   int loads;
      63             : #ifdef HAVE_PROC_UPTIME
      64             :   FILE *fp;
      65             : 
      66          10 :   fp = fopen ("/proc/uptime", "r");
      67          10 :   if (fp != NULL)
      68             :     {
      69             :       char buf[BUFSIZ];
      70          10 :       char *b = fgets (buf, BUFSIZ, fp);
      71          10 :       if (b == buf)
      72             :         {
      73             :           char *end_ptr;
      74          10 :           double upsecs = c_strtod (buf, &end_ptr);
      75          10 :           if (buf != end_ptr)
      76          10 :             uptime = (0 <= upsecs && upsecs < TYPE_MAXIMUM (time_t)
      77             :                       ? upsecs : -1);
      78             :         }
      79             : 
      80          10 :       fclose (fp);
      81             :     }
      82             : #endif /* HAVE_PROC_UPTIME */
      83             : 
      84             : #if HAVE_SYSCTL && defined CTL_KERN && defined KERN_BOOTTIME
      85             :   {
      86             :     /* FreeBSD specific: fetch sysctl "kern.boottime".  */
      87             :     static int request[2] = { CTL_KERN, KERN_BOOTTIME };
      88             :     struct timeval result;
      89             :     size_t result_len = sizeof result;
      90             : 
      91             :     if (sysctl (request, 2, &result, &result_len, NULL, 0) >= 0)
      92             :       boot_time = result.tv_sec;
      93             :   }
      94             : #endif
      95             : 
      96             : #if HAVE_OS_H /* BeOS */
      97             :   {
      98             :     system_info si;
      99             : 
     100             :     get_system_info (&si);
     101             :     boot_time = si.boot_time / 1000000;
     102             :   }
     103             : #endif
     104             : 
     105             : #if HAVE_UTMPX_H || HAVE_UTMP_H
     106             :   /* Loop through all the utmp entries we just read and count up the valid
     107             :      ones, also in the process possibly gleaning boottime. */
     108          20 :   while (n--)
     109             :     {
     110           0 :       entries += IS_USER_PROCESS (this);
     111           0 :       if (UT_TYPE_BOOT_TIME (this))
     112           0 :         boot_time = UT_TIME_MEMBER (this);
     113           0 :       ++this;
     114             :     }
     115             : #endif
     116          10 :   time_now = time (NULL);
     117             : #if defined HAVE_PROC_UPTIME
     118          10 :   if (uptime == 0)
     119             : #endif
     120             :     {
     121           0 :       if (boot_time == 0)
     122           0 :         error (EXIT_FAILURE, errno, _("couldn't get boot time"));
     123           0 :       uptime = time_now - boot_time;
     124             :     }
     125          10 :   updays = uptime / 86400;
     126          10 :   uphours = (uptime - (updays * 86400)) / 3600;
     127          10 :   upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60;
     128          10 :   tmn = localtime (&time_now);
     129          10 :   if (tmn)
     130          30 :     printf (_(" %2d:%02d%s  up "),
     131          20 :             ((tmn->tm_hour % 12) == 0 ? 12 : tmn->tm_hour % 12),
     132             :             /* FIXME: use strftime, not am, pm.  Uli reports that
     133             :                the german translation is meaningless.  */
     134          10 :             tmn->tm_min, (tmn->tm_hour < 12 ? _("am") : _("pm")));
     135             :   else
     136           0 :     printf (_(" ??:????  up "));
     137          10 :   if (uptime == (time_t) -1)
     138           0 :     printf (_("???? days ??:??,  "));
     139             :   else
     140             :     {
     141          10 :       if (0 < updays)
     142          10 :         printf (ngettext ("%ld day", "%ld days", select_plural (updays)),
     143             :                 updays);
     144          10 :       printf (" %2d:%02d,  ", uphours, upmins);
     145             :     }
     146          10 :   printf (ngettext ("%lu user", "%lu users", entries),
     147             :           (unsigned long int) entries);
     148             : 
     149             : #if defined HAVE_GETLOADAVG || defined C_GETLOADAVG
     150          10 :   loads = getloadavg (avg, 3);
     151             : #else
     152             :   loads = -1;
     153             : #endif
     154             : 
     155          10 :   if (loads == -1)
     156           0 :     putchar ('\n');
     157             :   else
     158             :     {
     159          10 :       if (loads > 0)
     160          10 :         printf (_(",  load average: %.2f"), avg[0]);
     161          10 :       if (loads > 1)
     162          10 :         printf (", %.2f", avg[1]);
     163          10 :       if (loads > 2)
     164          10 :         printf (", %.2f", avg[2]);
     165          10 :       if (loads > 0)
     166          10 :         putchar ('\n');
     167             :     }
     168          10 : }
     169             : 
     170             : /* Display the system uptime and the number of users on the system,
     171             :    according to utmp file FILENAME.  Use read_utmp OPTIONS to read the
     172             :    utmp file.  */
     173             : 
     174             : static void
     175          10 : uptime (const char *filename, int options)
     176             : {
     177             :   size_t n_users;
     178             :   STRUCT_UTMP *utmp_buf;
     179             : 
     180             : #if HAVE_UTMPX_H || HAVE_UTMP_H
     181          10 :   if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
     182           0 :     error (EXIT_FAILURE, errno, "%s", filename);
     183             : #endif
     184             : 
     185          10 :   print_uptime (n_users, utmp_buf);
     186          10 : }
     187             : 
     188             : void
     189          26 : usage (int status)
     190             : {
     191          26 :   if (status != EXIT_SUCCESS)
     192          24 :     fprintf (stderr, _("Try `%s --help' for more information.\n"),
     193             :              program_name);
     194             :   else
     195             :     {
     196           2 :       printf (_("Usage: %s [OPTION]... [ FILE ]\n"), program_name);
     197           2 :       printf (_("\
     198             : Print the current time, the length of time the system has been up,\n\
     199             : the number of users on the system, and the average number of jobs\n\
     200             : in the run queue over the last 1, 5 and 15 minutes.\n\
     201             : If FILE is not specified, use %s.  %s as FILE is common.\n\
     202             : \n\
     203             : "),
     204             :               UTMP_FILE, WTMP_FILE);
     205           2 :       fputs (HELP_OPTION_DESCRIPTION, stdout);
     206           2 :       fputs (VERSION_OPTION_DESCRIPTION, stdout);
     207           2 :       emit_bug_reporting_address ();
     208             :     }
     209          26 :   exit (status);
     210             : }
     211             : 
     212             : int
     213          37 : main (int argc, char **argv)
     214             : {
     215             :   initialize_main (&argc, &argv);
     216          37 :   program_name = argv[0];
     217          37 :   setlocale (LC_ALL, "");
     218             :   bindtextdomain (PACKAGE, LOCALEDIR);
     219             :   textdomain (PACKAGE);
     220             : 
     221          37 :   atexit (close_stdout);
     222             : 
     223          37 :   parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, VERSION,
     224             :                       usage, AUTHORS, (char const *) NULL);
     225          34 :   if (getopt_long (argc, argv, "", NULL, NULL) != -1)
     226           5 :     usage (EXIT_FAILURE);
     227             : 
     228          29 :   switch (argc - optind)
     229             :     {
     230           2 :     case 0:                     /* uptime */
     231           2 :       uptime (UTMP_FILE, READ_UTMP_CHECK_PIDS);
     232           2 :       break;
     233             : 
     234           8 :     case 1:                     /* uptime <utmp file> */
     235           8 :       uptime (argv[optind], 0);
     236           8 :       break;
     237             : 
     238          19 :     default:                    /* lose */
     239          19 :       error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
     240          19 :       usage (EXIT_FAILURE);
     241             :     }
     242             : 
     243          10 :   exit (EXIT_SUCCESS);
     244             : }

Generated by: LCOV version 1.10