stty: fix untranslated diagnostics
[coreutils.git] / src / uptime.c
blobbc31026c0e7f7aa1cf781c3e1046807e5ccca624
1 /* GNU's uptime.
2 Copyright (C) 1992-2023 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. */
19 #include <config.h>
20 #include <stdio.h>
22 #include <sys/types.h>
23 #include "system.h"
25 #if HAVE_SYSCTL && HAVE_SYS_SYSCTL_H && ! defined __GLIBC__
26 # include <sys/sysctl.h>
27 #endif
29 #if HAVE_OS_H
30 # include <OS.h>
31 #endif
33 #include "c-strtod.h"
34 #include "long-options.h"
35 #include "quote.h"
36 #include "readutmp.h"
37 #include "fprintftime.h"
39 /* The official name of this program (e.g., no 'g' prefix). */
40 #define PROGRAM_NAME "uptime"
42 #define AUTHORS \
43 proper_name ("Joseph Arceneaux"), \
44 proper_name ("David MacKenzie"), \
45 proper_name ("Kaveh Ghazi")
47 static void
48 print_uptime (size_t n, const STRUCT_UTMP *this)
50 size_t entries = 0;
51 time_t boot_time = 0;
52 time_t time_now;
53 time_t uptime = 0;
54 long int updays;
55 int uphours;
56 int upmins;
57 struct tm *tmn;
58 double avg[3];
59 int loads;
60 #ifdef HAVE_PROC_UPTIME
61 FILE *fp;
63 fp = fopen ("/proc/uptime", "r");
64 if (fp != nullptr)
66 char buf[BUFSIZ];
67 char *b = fgets (buf, BUFSIZ, fp);
68 if (b == buf)
70 char *end_ptr;
71 double upsecs = c_strtod (buf, &end_ptr);
72 if (buf != end_ptr)
73 uptime = (0 <= upsecs && upsecs < TYPE_MAXIMUM (time_t)
74 ? upsecs : -1);
77 fclose (fp);
79 #endif /* HAVE_PROC_UPTIME */
81 #if HAVE_SYSCTL && ! defined __GLIBC__ \
82 && defined CTL_KERN && defined KERN_BOOTTIME
84 /* FreeBSD specific: fetch sysctl "kern.boottime". */
85 static int request[2] = { CTL_KERN, KERN_BOOTTIME };
86 struct timeval result;
87 size_t result_len = sizeof result;
89 if (sysctl (request, 2, &result, &result_len, nullptr, 0) >= 0)
90 boot_time = result.tv_sec;
92 #endif
94 #if HAVE_OS_H /* BeOS */
96 system_info si;
98 get_system_info (&si);
99 boot_time = si.boot_time / 1000000;
101 #endif
103 #if HAVE_STRUCT_UTMP_UT_TYPE || HAVE_STRUCT_UTMPX_UT_TYPE
104 /* Loop through all the utmp entries we just read and count up the valid
105 ones, also in the process possibly gleaning boottime. */
106 while (n--)
108 entries += IS_USER_PROCESS (this);
109 if (UT_TYPE_BOOT_TIME (this))
110 boot_time = UT_TIME_MEMBER (this);
111 ++this;
113 #else
114 (void) n;
115 (void) this;
116 #endif
118 time_now = time (nullptr);
119 #if defined HAVE_PROC_UPTIME
120 if (uptime == 0)
121 #endif
123 if (boot_time == 0)
124 error (EXIT_FAILURE, errno, _("couldn't get boot time"));
125 uptime = time_now - boot_time;
127 updays = uptime / 86400;
128 uphours = (uptime - (updays * 86400)) / 3600;
129 upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60;
130 tmn = localtime (&time_now);
131 /* procps' version of uptime also prints the seconds field, but
132 previous versions of coreutils don't. */
133 if (tmn)
134 /* TRANSLATORS: This prints the current clock time. */
135 fprintftime (stdout, _(" %H:%M:%S "), tmn, 0, 0);
136 else
137 printf (_(" ??:???? "));
138 if (uptime == (time_t) -1)
139 printf (_("up ???? days ??:??, "));
140 else
142 if (0 < updays)
143 printf (ngettext ("up %ld day %2d:%02d, ",
144 "up %ld days %2d:%02d, ",
145 select_plural (updays)),
146 updays, uphours, upmins);
147 else
148 printf (_("up %2d:%02d, "), uphours, upmins);
150 printf (ngettext ("%lu user", "%lu users", select_plural (entries)),
151 (unsigned long int) entries);
153 loads = getloadavg (avg, 3);
155 if (loads == -1)
156 putchar ('\n');
157 else
159 if (loads > 0)
160 printf (_(", load average: %.2f"), avg[0]);
161 if (loads > 1)
162 printf (", %.2f", avg[1]);
163 if (loads > 2)
164 printf (", %.2f", avg[2]);
165 if (loads > 0)
166 putchar ('\n');
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. */
174 static _Noreturn void
175 uptime (char const *filename, int options)
177 size_t n_users;
178 STRUCT_UTMP *utmp_buf = nullptr;
180 #if HAVE_STRUCT_UTMP_UT_TYPE || HAVE_STRUCT_UTMPX_UT_TYPE
181 if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
182 error (EXIT_FAILURE, errno, "%s", quotef (filename));
183 #endif
185 print_uptime (n_users, utmp_buf);
187 exit (EXIT_SUCCESS);
190 void
191 usage (int status)
193 if (status != EXIT_SUCCESS)
194 emit_try_help ();
195 else
197 printf (_("Usage: %s [OPTION]... [FILE]\n"), program_name);
198 printf (_("\
199 Print the current time, the length of time the system has been up,\n\
200 the number of users on the system, and the average number of jobs\n\
201 in the run queue over the last 1, 5 and 15 minutes."));
202 #ifdef __linux__
203 /* It would be better to introduce a configure test for this,
204 but such a test is hard to write. For the moment then, we
205 have a hack which depends on the preprocessor used at compile
206 time to tell us what the running kernel is. Ugh. */
207 printf (_(" \
208 Processes in\n\
209 an uninterruptible sleep state also contribute to the load average.\n"));
210 #else
211 printf (_("\n"));
212 #endif
213 printf (_("\
214 If FILE is not specified, use %s. %s as FILE is common.\n\
215 \n"),
216 UTMP_FILE, WTMP_FILE);
217 fputs (HELP_OPTION_DESCRIPTION, stdout);
218 fputs (VERSION_OPTION_DESCRIPTION, stdout);
219 emit_ancillary_info (PROGRAM_NAME);
221 exit (status);
225 main (int argc, char **argv)
227 initialize_main (&argc, &argv);
228 set_program_name (argv[0]);
229 setlocale (LC_ALL, "");
230 bindtextdomain (PACKAGE, LOCALEDIR);
231 textdomain (PACKAGE);
233 atexit (close_stdout);
235 parse_gnu_standard_options_only (argc, argv, PROGRAM_NAME, PACKAGE_NAME,
236 Version, true, usage, AUTHORS,
237 (char const *) nullptr);
239 switch (argc - optind)
241 case 0: /* uptime */
242 uptime (UTMP_FILE, READ_UTMP_CHECK_PIDS);
243 break;
245 case 1: /* uptime <utmp file> */
246 uptime (argv[optind], 0);
247 break;
249 default: /* lose */
250 error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
251 usage (EXIT_FAILURE);