2 Copyright (C) 1992-2024 Free Software Foundation, Inc.
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.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Created by hacking who.c by Kaveh Ghazi ghazi@caip.rutgers.edu. */
22 #include <sys/types.h>
26 #include "long-options.h"
29 #include "fprintftime.h"
31 /* The official name of this program (e.g., no 'g' prefix). */
32 #define PROGRAM_NAME "uptime"
35 proper_name ("Joseph Arceneaux"), \
36 proper_name ("David MacKenzie"), \
37 proper_name ("Kaveh Ghazi")
40 print_uptime (idx_t n
, struct gl_utmp
const *utmp_buf
)
42 int status
= EXIT_SUCCESS
;
45 /* Loop through all the utmp entries we just read and count up the valid
46 ones, also in the process possibly gleaning boottime. */
48 for (idx_t i
= 0; i
< n
; i
++)
50 struct gl_utmp
const *this = &utmp_buf
[i
];
51 entries
+= IS_USER_PROCESS (this);
52 if (UT_TYPE_BOOT_TIME (this))
53 boot_time
= this->ut_ts
.tv_sec
;
55 /* The gnulib module 'readutmp' is supposed to provide a BOOT_TIME entry
59 error (0, errno
, _("couldn't get boot time"));
60 status
= EXIT_FAILURE
;
63 time_t time_now
= time (nullptr);
64 struct tm
*tmn
= time_now
== (time_t) -1 ? nullptr : localtime (&time_now
);
65 /* procps' version of uptime also prints the seconds field, but
66 previous versions of coreutils don't. */
68 /* TRANSLATORS: This prints the current clock time. */
69 fprintftime (stdout
, _(" %H:%M:%S "), tmn
, 0, 0);
72 printf (_(" ??:???? "));
73 status
= EXIT_FAILURE
;
77 if (time_now
== (time_t) -1 || boot_time
== 0
78 || ckd_sub (&uptime
, time_now
, boot_time
) || uptime
< 0)
80 printf (_("up ???? days ??:??, "));
81 status
= EXIT_FAILURE
;
85 intmax_t updays
= uptime
/ 86400;
86 int uphours
= uptime
% 86400 / 3600;
87 int upmins
= uptime
% 86400 % 3600 / 60;
89 printf (ngettext ("up %jd day %2d:%02d, ",
90 "up %jd days %2d:%02d, ",
91 select_plural (updays
)),
92 updays
, uphours
, upmins
);
94 printf (_("up %2d:%02d, "), uphours
, upmins
);
97 printf (ngettext ("%td user", "%td users", select_plural (entries
)),
101 int loads
= getloadavg (avg
, 3);
108 printf (_(", load average: %.2f"), avg
[0]);
110 printf (", %.2f", avg
[1]);
112 printf (", %.2f", avg
[2]);
120 /* Display the system uptime and the number of users on the system,
121 according to utmp file FILENAME. Use read_utmp OPTIONS to read the
124 static _Noreturn
void
125 uptime (char const *filename
, int options
)
128 struct gl_utmp
*utmp_buf
;
129 int read_utmp_status
= (read_utmp (filename
, &n_users
, &utmp_buf
, options
) < 0
130 ? EXIT_FAILURE
: EXIT_SUCCESS
);
131 if (read_utmp_status
!= EXIT_SUCCESS
)
133 error (0, errno
, "%s", quotef (filename
));
138 int print_uptime_status
= print_uptime (n_users
, utmp_buf
);
139 exit (MAX (read_utmp_status
, print_uptime_status
));
145 if (status
!= EXIT_SUCCESS
)
149 printf (_("Usage: %s [OPTION]... [FILE]\n"), program_name
);
151 Print the current time, the length of time the system has been up,\n\
152 the number of users on the system, and the average number of jobs\n\
153 in the run queue over the last 1, 5 and 15 minutes."));
155 /* It would be better to introduce a configure test for this,
156 but such a test is hard to write. For the moment then, we
157 have a hack which depends on the preprocessor used at compile
158 time to tell us what the running kernel is. Ugh. */
161 an uninterruptible sleep state also contribute to the load average.\n"));
166 If FILE is not specified, use %s. %s as FILE is common.\n\
168 UTMP_FILE
, WTMP_FILE
);
169 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
170 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
171 emit_ancillary_info (PROGRAM_NAME
);
177 main (int argc
, char **argv
)
179 initialize_main (&argc
, &argv
);
180 set_program_name (argv
[0]);
181 setlocale (LC_ALL
, "");
182 bindtextdomain (PACKAGE
, LOCALEDIR
);
183 textdomain (PACKAGE
);
185 atexit (close_stdout
);
187 parse_gnu_standard_options_only (argc
, argv
, PROGRAM_NAME
, PACKAGE_NAME
,
188 Version
, true, usage
, AUTHORS
,
189 (char const *) nullptr);
191 switch (argc
- optind
)
194 uptime (UTMP_FILE
, READ_UTMP_CHECK_PIDS
);
197 case 1: /* uptime <utmp file> */
198 uptime (argv
[optind
], 0);
202 error (0, 0, _("extra operand %s"), quote (argv
[optind
+ 1]));
203 usage (EXIT_FAILURE
);