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"
40 /* The official name of this program (e.g., no `g' prefix). */
41 #define PROGRAM_NAME "uptime"
44 proper_name ("Joseph Arceneaux"), \
45 proper_name ("David MacKenzie"), \
46 proper_name ("Kaveh Ghazi")
51 print_uptime (size_t n
, const STRUCT_UTMP
*this)
63 #ifdef HAVE_PROC_UPTIME
66 fp
= fopen ("/proc/uptime", "r");
70 char *b
= fgets (buf
, BUFSIZ
, fp
);
74 double upsecs
= c_strtod (buf
, &end_ptr
);
76 uptime
= (0 <= upsecs
&& upsecs
< TYPE_MAXIMUM (time_t)
82 #endif /* HAVE_PROC_UPTIME */
84 #if HAVE_SYSCTL && defined CTL_KERN && defined KERN_BOOTTIME
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
;
91 if (sysctl (request
, 2, &result
, &result_len
, NULL
, 0) >= 0)
92 boot_time
= result
.tv_sec
;
96 #if HAVE_OS_H /* BeOS */
100 get_system_info (&si
);
101 boot_time
= si
.boot_time
/ 1000000;
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. */
110 entries
+= IS_USER_PROCESS (this);
111 if (UT_TYPE_BOOT_TIME (this))
112 boot_time
= UT_TIME_MEMBER (this);
116 time_now
= time (NULL
);
117 #if defined HAVE_PROC_UPTIME
122 error (EXIT_FAILURE
, errno
, _("couldn't get boot time"));
123 uptime
= time_now
- boot_time
;
125 updays
= uptime
/ 86400;
126 uphours
= (uptime
- (updays
* 86400)) / 3600;
127 upmins
= (uptime
- (updays
* 86400) - (uphours
* 3600)) / 60;
128 tmn
= localtime (&time_now
);
130 printf (_(" %2d:%02d%s up "),
131 ((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 tmn
->tm_min
, (tmn
->tm_hour
< 12 ? _("am") : _("pm")));
136 printf (_(" ??:???? up "));
137 if (uptime
== (time_t) -1)
138 printf (_("???? days ??:??, "));
142 printf (ngettext ("%ld day", "%ld days", select_plural (updays
)),
144 printf (" %2d:%02d, ", uphours
, upmins
);
146 printf (ngettext ("%lu user", "%lu users", entries
),
147 (unsigned long int) entries
);
149 #if defined HAVE_GETLOADAVG || defined C_GETLOADAVG
150 loads
= getloadavg (avg
, 3);
160 printf (_(", load average: %.2f"), avg
[0]);
162 printf (", %.2f", avg
[1]);
164 printf (", %.2f", avg
[2]);
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
175 uptime (const char *filename
, int options
)
178 STRUCT_UTMP
*utmp_buf
;
180 #if HAVE_UTMPX_H || HAVE_UTMP_H
181 if (read_utmp (filename
, &n_users
, &utmp_buf
, options
) != 0)
182 error (EXIT_FAILURE
, errno
, "%s", filename
);
185 print_uptime (n_users
, utmp_buf
);
191 if (status
!= EXIT_SUCCESS
)
192 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
196 printf (_("Usage: %s [OPTION]... [ FILE ]\n"), program_name
);
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\
204 UTMP_FILE
, WTMP_FILE
);
205 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
206 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
207 emit_bug_reporting_address ();
213 main (int argc
, char **argv
)
215 initialize_main (&argc
, &argv
);
216 set_program_name (argv
[0]);
217 setlocale (LC_ALL
, "");
218 bindtextdomain (PACKAGE
, LOCALEDIR
);
219 textdomain (PACKAGE
);
221 atexit (close_stdout
);
223 parse_long_options (argc
, argv
, PROGRAM_NAME
, PACKAGE_NAME
, VERSION
,
224 usage
, AUTHORS
, (char const *) NULL
);
225 if (getopt_long (argc
, argv
, "", NULL
, NULL
) != -1)
226 usage (EXIT_FAILURE
);
228 switch (argc
- optind
)
231 uptime (UTMP_FILE
, READ_UTMP_CHECK_PIDS
);
234 case 1: /* uptime <utmp file> */
235 uptime (argv
[optind
], 0);
239 error (0, 0, _("extra operand %s"), quote (argv
[optind
+ 1]));
240 usage (EXIT_FAILURE
);