2 Copyright (C) 1992-2013 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")
50 print_uptime (size_t n
, const STRUCT_UTMP
*this)
62 #ifdef HAVE_PROC_UPTIME
65 fp
= fopen ("/proc/uptime", "r");
69 char *b
= fgets (buf
, BUFSIZ
, fp
);
73 double upsecs
= c_strtod (buf
, &end_ptr
);
75 uptime
= (0 <= upsecs
&& upsecs
< TYPE_MAXIMUM (time_t)
81 #endif /* HAVE_PROC_UPTIME */
83 #if HAVE_SYSCTL && defined CTL_KERN && defined KERN_BOOTTIME
85 /* FreeBSD specific: fetch sysctl "kern.boottime". */
86 static int request
[2] = { CTL_KERN
, KERN_BOOTTIME
};
87 struct timeval result
;
88 size_t result_len
= sizeof result
;
90 if (sysctl (request
, 2, &result
, &result_len
, NULL
, 0) >= 0)
91 boot_time
= result
.tv_sec
;
95 #if HAVE_OS_H /* BeOS */
99 get_system_info (&si
);
100 boot_time
= si
.boot_time
/ 1000000;
104 #if HAVE_UTMPX_H || HAVE_UTMP_H
105 /* Loop through all the utmp entries we just read and count up the valid
106 ones, also in the process possibly gleaning boottime. */
109 entries
+= IS_USER_PROCESS (this);
110 if (UT_TYPE_BOOT_TIME (this))
111 boot_time
= UT_TIME_MEMBER (this);
119 time_now
= time (NULL
);
120 #if defined HAVE_PROC_UPTIME
125 error (EXIT_FAILURE
, errno
, _("couldn't get boot time"));
126 uptime
= time_now
- boot_time
;
128 updays
= uptime
/ 86400;
129 uphours
= (uptime
- (updays
* 86400)) / 3600;
130 upmins
= (uptime
- (updays
* 86400) - (uphours
* 3600)) / 60;
131 tmn
= localtime (&time_now
);
132 /* procps' version of uptime also prints the seconds field, but
133 previous versions of coreutils don't. */
135 /* TRANSLATORS: This prints the current clock time. */
136 fprintftime (stdout
, _(" %H:%M%P "), tmn
, 0, 0);
138 printf (_(" ??:???? "));
139 if (uptime
== (time_t) -1)
140 printf (_("up ???? days ??:??, "));
144 printf (ngettext ("up %ld day %2d:%02d, ",
145 "up %ld days %2d:%02d, ",
146 select_plural (updays
)),
147 updays
, uphours
, upmins
);
149 printf (_("up %2d:%02d, "), uphours
, upmins
);
151 printf (ngettext ("%lu user", "%lu users", select_plural (entries
)),
152 (unsigned long int) entries
);
154 loads
= getloadavg (avg
, 3);
161 printf (_(", load average: %.2f"), avg
[0]);
163 printf (", %.2f", avg
[1]);
165 printf (", %.2f", avg
[2]);
171 /* Display the system uptime and the number of users on the system,
172 according to utmp file FILENAME. Use read_utmp OPTIONS to read the
176 uptime (const char *filename
, int options
)
179 STRUCT_UTMP
*utmp_buf
= NULL
;
181 #if HAVE_UTMPX_H || HAVE_UTMP_H
182 if (read_utmp (filename
, &n_users
, &utmp_buf
, options
) != 0)
183 error (EXIT_FAILURE
, errno
, "%s", filename
);
186 print_uptime (n_users
, utmp_buf
);
188 IF_LINT (free (utmp_buf
));
194 if (status
!= EXIT_SUCCESS
)
198 printf (_("Usage: %s [OPTION]... [FILE]\n"), program_name
);
200 Print the current time, the length of time the system has been up,\n\
201 the number of users on the system, and the average number of jobs\n\
202 in the run queue over the last 1, 5 and 15 minutes."));
204 /* It would be better to introduce a configure test for this,
205 but such a test is hard to write. For the moment then, we
206 have a hack which depends on the preprocessor used at compile
207 time to tell us what the running kernel is. Ugh. */
210 an uninterruptible sleep state also contribute to the load average.\n"));
215 If FILE is not specified, use %s. %s as FILE is common.\n\
217 UTMP_FILE
, WTMP_FILE
);
218 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
219 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
220 emit_ancillary_info ();
226 main (int argc
, char **argv
)
228 initialize_main (&argc
, &argv
);
229 set_program_name (argv
[0]);
230 setlocale (LC_ALL
, "");
231 bindtextdomain (PACKAGE
, LOCALEDIR
);
232 textdomain (PACKAGE
);
234 atexit (close_stdout
);
236 parse_long_options (argc
, argv
, PROGRAM_NAME
, PACKAGE_NAME
, Version
,
237 usage
, AUTHORS
, (char const *) NULL
);
238 if (getopt_long (argc
, argv
, "", NULL
, NULL
) != -1)
239 usage (EXIT_FAILURE
);
241 switch (argc
- optind
)
244 uptime (UTMP_FILE
, READ_UTMP_CHECK_PIDS
);
247 case 1: /* uptime <utmp file> */
248 uptime (argv
[optind
], 0);
252 error (0, 0, _("extra operand %s"), quote (argv
[optind
+ 1]));
253 usage (EXIT_FAILURE
);