2 Copyright (C) 1992-2002, 2004-2008 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 <http://www.gnu.org/licenses/>. */
17 /* Created by hacking who.c by Kaveh Ghazi ghazi@caip.rutgers.edu. */
23 #include <sys/types.h>
26 #if HAVE_SYSCTL && HAVE_SYS_SYSCTL_H
27 # include <sys/sysctl.h>
36 #include "long-options.h"
39 #include "fprintftime.h"
41 /* The official name of this program (e.g., no `g' prefix). */
42 #define PROGRAM_NAME "uptime"
45 proper_name ("Joseph Arceneaux"), \
46 proper_name ("David MacKenzie"), \
47 proper_name ("Kaveh Ghazi")
52 print_uptime (size_t n, const STRUCT_UTMP *this)
64 #ifdef HAVE_PROC_UPTIME
67 fp = fopen ("/proc/uptime", "r");
71 char *b = fgets (buf, BUFSIZ, fp);
75 double upsecs = c_strtod (buf, &end_ptr);
77 uptime = (0 <= upsecs && upsecs < TYPE_MAXIMUM (time_t)
83 #endif /* HAVE_PROC_UPTIME */
85 #if HAVE_SYSCTL && defined CTL_KERN && defined KERN_BOOTTIME
87 /* FreeBSD specific: fetch sysctl "kern.boottime". */
88 static int request[2] = { CTL_KERN, KERN_BOOTTIME };
89 struct timeval result;
90 size_t result_len = sizeof result;
92 if (sysctl (request, 2, &result, &result_len, NULL, 0) >= 0)
93 boot_time = result.tv_sec;
97 #if HAVE_OS_H /* BeOS */
101 get_system_info (&si);
102 boot_time = si.boot_time / 1000000;
106 #if HAVE_UTMPX_H || HAVE_UTMP_H
107 /* Loop through all the utmp entries we just read and count up the valid
108 ones, also in the process possibly gleaning boottime. */
111 entries += IS_USER_PROCESS (this);
112 if (UT_TYPE_BOOT_TIME (this))
113 boot_time = UT_TIME_MEMBER (this);
117 time_now = time (NULL);
118 #if defined HAVE_PROC_UPTIME
123 error (EXIT_FAILURE, errno, _("couldn't get boot time"));
124 uptime = time_now - boot_time;
126 updays = uptime / 86400;
127 uphours = (uptime - (updays * 86400)) / 3600;
128 upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60;
129 tmn = localtime (&time_now);
130 /* procps' version of uptime also prints the seconds field, but
131 previous versions of coreutils don't. */
133 fprintftime (stdout, _(" %H:%M%P up "), tmn, 0, 0);
135 printf (_(" ??:???? up "));
136 if (uptime == (time_t) -1)
137 printf (_("???? days ??:??, "));
141 printf (ngettext ("%ld day", "%ld days", select_plural (updays)),
143 printf (" %2d:%02d, ", uphours, upmins);
145 printf (ngettext ("%lu user", "%lu users", entries),
146 (unsigned long int) entries);
148 #if defined HAVE_GETLOADAVG || defined C_GETLOADAVG
149 loads = getloadavg (avg, 3);
159 printf (_(", load average: %.2f"), avg[0]);
161 printf (", %.2f", avg[1]);
163 printf (", %.2f", avg[2]);
169 /* Display the system uptime and the number of users on the system,
170 according to utmp file FILENAME. Use read_utmp OPTIONS to read the
174 uptime (const char *filename, int options)
177 STRUCT_UTMP *utmp_buf;
179 #if HAVE_UTMPX_H || HAVE_UTMP_H
180 if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
181 error (EXIT_FAILURE, errno, "%s", filename);
184 print_uptime (n_users, utmp_buf);
190 if (status != EXIT_SUCCESS)
191 fprintf (stderr, _("Try `%s --help' for more information.\n"),
195 printf (_("Usage: %s [OPTION]... [FILE]\n"), program_name);
197 Print the current time, the length of time the system has been up,\n\
198 the number of users on the system, and the average number of jobs\n\
199 in the run queue over the last 1, 5 and 15 minutes."));
201 /* It would be better to introduce a configure test for this,
202 but such a test is hard to write. For the moment then, we
203 have a hack which depends on the preprocessor used at compile
204 time to tell us what the running kernel is. Ugh. */
207 an uninterruptible sleep state also contribute to the load average.\n"));
212 If FILE is not specified, use %s. %s as FILE is common.\n\
214 UTMP_FILE, WTMP_FILE);
215 fputs (HELP_OPTION_DESCRIPTION, stdout);
216 fputs (VERSION_OPTION_DESCRIPTION, stdout);
217 emit_bug_reporting_address ();
223 main (int argc, char **argv)
225 initialize_main (&argc, &argv);
226 set_program_name (argv[0]);
227 setlocale (LC_ALL, "");
228 bindtextdomain (PACKAGE, LOCALEDIR);
229 textdomain (PACKAGE);
231 atexit (close_stdout);
233 parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
234 usage, AUTHORS, (char const *) NULL);
235 if (getopt_long (argc, argv, "", NULL, NULL) != -1)
236 usage (EXIT_FAILURE);
238 switch (argc - optind)
241 uptime (UTMP_FILE, READ_UTMP_CHECK_PIDS);
244 case 1: /* uptime <utmp file> */
245 uptime (argv[optind], 0);
249 error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
250 usage (EXIT_FAILURE);