/* GNU's uptime. This is the uptime utility
Copyright (C) 1992-2018 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */ The GNUv3 license
/* Created by hacking who.c by Kaveh Ghazi ghazi@caip.rutgers.edu. */
#include <config.h> Provides system specific information
#include <getopt.h> ...!includes auto-comment...
#include <stdio.h> Provides standard I/O capability
#include <sys/types.h> Provides system data types
#include "system.h" ...!includes auto-comment...
#if HAVE_SYSCTL && HAVE_SYS_SYSCTL_H Line 26
# include <sys/sysctl.h> Line 27
#endif Line 28
#if HAVE_OS_H Line 30
# include <OS.h> Line 31
#endif Line 32
#include "c-strtod.h" ...!includes auto-comment...
#include "die.h" ...!includes auto-comment...
#include "error.h" ...!includes auto-comment...
#include "long-options.h" ...!includes auto-comment...
#include "quote.h" ...!includes auto-comment...
#include "readutmp.h" ...!includes auto-comment...
#include "fprintftime.h" ...!includes auto-comment...
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "uptime" Line 43
#define AUTHORS \ Line 45
proper_name ("Joseph Arceneaux"), \ Line 46
proper_name ("David MacKenzie"), \ Line 47
proper_name ("Kaveh Ghazi") Line 48
static struct option const long_options[] = Line 50
{
{NULL, 0, NULL, 0} Line 52
}; Block 1
static void Line 55
print_uptime (size_t n, const STRUCT_UTMP *this) Line 56
{
size_t entries = 0; Line 58
time_t boot_time = 0; Line 59
time_t time_now; Line 60
time_t uptime = 0; Line 61
long int updays; Line 62
int uphours; Line 63
int upmins; Line 64
struct tm *tmn; Line 65
double avg[3]; Line 66
int loads; Line 67
#ifdef HAVE_PROC_UPTIME Line 68
FILE *fp; Line 69
fp = fopen ("/proc/uptime", "r"); Line 71...!syscalls auto-comment...
if (fp != NULL) Line 72
{
char buf[BUFSIZ]; Line 74
char *b = fgets (buf, BUFSIZ, fp); Line 75
if (b == buf) Line 76
{
char *end_ptr; Line 78
double upsecs = c_strtod (buf, &end_ptr); Line 79
if (buf != end_ptr) Line 80
uptime = (0 <= upsecs && upsecs < TYPE_MAXIMUM (time_t) Line 81
? upsecs : -1); Line 82
}
fclose (fp); Line 85...!syscalls auto-comment...
}
#endif /* HAVE_PROC_UPTIME */ Line 87
#if HAVE_SYSCTL && defined CTL_KERN && defined KERN_BOOTTIME Line 89
{
/* FreeBSD specific: fetch sysctl "kern.boottime". */
static int request[2] = { CTL_KERN, KERN_BOOTTIME }; Line 92
struct timeval result; Line 93
size_t result_len = sizeof result; Line 94
if (sysctl (request, 2, &result, &result_len, NULL, 0) >= 0) Line 96
boot_time = result.tv_sec; Line 97
}
#endif Line 99
#if HAVE_OS_H /* BeOS */ Line 101
{
system_info si; Line 103
get_system_info (&si); Line 105
boot_time = si.boot_time / 1000000; Line 106
}
#endif Line 108
#if HAVE_UTMPX_H || HAVE_UTMP_H Line 110
/* Loop through all the utmp entries we just read and count up the valid
ones, also in the process possibly gleaning boottime. */
while (n--) Line 113
{
entries += IS_USER_PROCESS (this); Line 115
if (UT_TYPE_BOOT_TIME (this)) Line 116
boot_time = UT_TIME_MEMBER (this); Line 117
++this; Line 118
}
#else Line 120
(void) n; Line 121
(void) this; Line 122
#endif Line 123
time_now = time (NULL); Line 125
#if defined HAVE_PROC_UPTIME Line 126
if (uptime == 0) Line 127
#endif Line 128
{
if (boot_time == 0) Line 130
die (EXIT_FAILURE, errno, _("couldn't get boot time")); Line 131
uptime = time_now - boot_time; Line 132
}
updays = uptime / 86400; Line 134
uphours = (uptime - (updays * 86400)) / 3600; Line 135
upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60; Line 136
tmn = localtime (&time_now); Line 137
/* procps' version of uptime also prints the seconds field, but
previous versions of coreutils don't. */
if (tmn) Line 140
/* TRANSLATORS: This prints the current clock time. */
fprintftime (stdout, _(" %H:%M:%S "), tmn, 0, 0); Line 142
else Line 143
printf (_(" ??:???? ")); Line 144
if (uptime == (time_t) -1) Line 145
printf (_("up ???? days ??:??, ")); Line 146
else Line 147
{
if (0 < updays) Line 149
printf (ngettext ("up %ld day %2d:%02d, ", Line 150
"up %ld days %2d:%02d, ", Line 151
select_plural (updays)), Line 152
updays, uphours, upmins); Line 153
else Line 154
printf (_("up %2d:%02d, "), uphours, upmins); Line 155
}
printf (ngettext ("%lu user", "%lu users", select_plural (entries)), Line 157
(unsigned long int) entries); Line 158
loads = getloadavg (avg, 3); Line 160
if (loads == -1) Line 162
putchar ('\n'); Line 163
else Line 164
{
if (loads > 0) Line 166
printf (_(", load average: %.2f"), avg[0]); Line 167
if (loads > 1) Line 168
printf (", %.2f", avg[1]); Line 169
if (loads > 2) Line 170
printf (", %.2f", avg[2]); Line 171
if (loads > 0) Line 172
putchar ('\n'); Line 173
}
} Block 2
/* Display the system uptime and the number of users on the system,
according to utmp file FILENAME. Use read_utmp OPTIONS to read the
utmp file. */
static void Line 181
uptime (const char *filename, int options) Line 182
{
size_t n_users; Line 184
STRUCT_UTMP *utmp_buf = NULL; Line 185
#if HAVE_UTMPX_H || HAVE_UTMP_H Line 187
if (read_utmp (filename, &n_users, &utmp_buf, options) != 0) Line 188
die (EXIT_FAILURE, errno, "%s", quotef (filename)); Line 189
#endif Line 190
print_uptime (n_users, utmp_buf); Line 192
IF_LINT (free (utmp_buf)); Line 194
} Block 3
void Line 197
usage (int status) Line 198
{
if (status != EXIT_SUCCESS) Line 200
emit_try_help (); ...!common auto-comment...
else Line 202
{
printf (_("Usage: %s [OPTION]... [FILE]\n"), program_name); Line 204
printf (_("\ Line 205
Print the current time, the length of time the system has been up,\n\ Line 206
the number of users on the system, and the average number of jobs\n\ Line 207
in the run queue over the last 1, 5 and 15 minutes.")); Line 208
#ifdef __linux__ Line 209
/* It would be better to introduce a configure test for this,
but such a test is hard to write. For the moment then, we
have a hack which depends on the preprocessor used at compile
time to tell us what the running kernel is. Ugh. */
printf (_(" \ Line 214
Processes in\n\ Line 215
an uninterruptible sleep state also contribute to the load average.\n")); Line 216
#else Line 217
printf (_("\n")); Line 218
#endif Line 219
printf (_("\ Line 220
If FILE is not specified, use %s. %s as FILE is common.\n\ Line 221
\n"), Line 222
UTMP_FILE, WTMP_FILE); Line 223
fputs (HELP_OPTION_DESCRIPTION, stdout); Line 224
fputs (VERSION_OPTION_DESCRIPTION, stdout); Line 225
emit_ancillary_info (PROGRAM_NAME); Line 226
}
exit (status); Line 228
} Block 4
int
main (int argc, char **argv) Line 232
{
initialize_main (&argc, &argv); VMS-specific entry point handling wildcard expansion
set_program_name (argv[0]); Retains program name and discards path
setlocale (LC_ALL, ""); Sets up internationalization (i18n)
bindtextdomain (PACKAGE, LOCALEDIR); Assigns i18n directorySets text domain for _() [gettext()] function
textdomain (PACKAGE); Sets text domain for _() [gettext()] function
atexit (close_stdout); Close stdout on exit (see gnulib)
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version, ...!common auto-comment...
usage, AUTHORS, (char const *) NULL); Line 243
if (getopt_long (argc, argv, "", long_options, NULL) != -1) Line 244
usage (EXIT_FAILURE); Line 245
switch (argc - optind) Line 247
{
case 0: /* uptime */ Line 249
uptime (UTMP_FILE, READ_UTMP_CHECK_PIDS); Line 250
break; Line 251
case 1: /* uptime <utmp file> */ Line 253
uptime (argv[optind], 0); Line 254
break; Line 255
default: /* lose */ Line 257
error (0, 0, _("extra operand %s"), quote (argv[optind + 1])); Line 258
usage (EXIT_FAILURE); Line 259
}
return EXIT_SUCCESS; Line 262
}