From f05406318b2ae83404f8c9fa16f837202e6b8ed8 Mon Sep 17 00:00:00 2001 From: Gary Mills Date: Thu, 19 Dec 2013 12:02:19 -0600 Subject: [PATCH] 2849 uptime should use locale settings for current time Reviewed by: Garrett D'Amore Approved by: Robert Mustacchi --- usr/src/cmd/w/w.c | 92 +++++++++++++++++++++----------------------- usr/src/cmd/whodo/whodo.c | 95 +++++++++++++++++++++------------------------- usr/src/man/man1/w.1 | 20 ++++++---- usr/src/man/man1m/whodo.1m | 20 ++++++---- 4 files changed, 112 insertions(+), 115 deletions(-) diff --git a/usr/src/cmd/w/w.c b/usr/src/cmd/w/w.c index b5eb04d3af..0c67ba9269 100644 --- a/usr/src/cmd/w/w.c +++ b/usr/src/cmd/w/w.c @@ -79,7 +79,7 @@ static struct utmpx dummy; /* Print minimum field widths. */ #define LOGIN_WIDTH 8 -#define LINE_WIDTH 12 +#define LINE_WIDTH 8 #define DIV60(t) ((t+30)/60) /* x/60 rounded */ @@ -127,9 +127,8 @@ static time_t findidle(char *); static void clnarglist(char *); static void showtotals(struct uproc *); static void calctotals(struct uproc *); -static void prttime(time_t, char *); +static void prttime(time_t, int); static void prtat(time_t *time); -static void checkampm(char *str); static char *prog; /* pointer to invocation name */ static int header = 1; /* true if -h flag: don't print heading */ @@ -276,7 +275,7 @@ main(int argc, char *argv[]) uptime %= (60*60); mins = uptime / 60; - PRINTF((gettext(" up"))); + PRINTF((gettext("up"))); if (days > 0) PRINTF((gettext( " %d day(s),"), days)); @@ -308,11 +307,13 @@ main(int argc, char *argv[]) exit(0); if (lflag) { - PRINTF((dcgettext(NULL, "User tty " - "login@ idle JCPU PCPU what\n", LC_TIME))); + PRINTF((dcgettext(NULL, "User tty " + "login@ idle JCPU PCPU what\n", + LC_TIME))); } else { PRINTF((dcgettext(NULL, - "User tty idle what\n", LC_TIME))); + "User tty idle what\n", + LC_TIME))); } if (fflush(stdout) == EOF) { @@ -485,13 +486,14 @@ retry: /* print tty user is on */ if (lflag) { - PRINTF(("%-*.*s", LINE_WIDTH, LMAX, ut->ut_line)); + PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, ut->ut_line)); } else { if (ut->ut_line[0] == 'p' && ut->ut_line[1] == 't' && ut->ut_line[2] == 's' && ut->ut_line[3] == '/') { - PRINTF(("%-*.3s", LMAX, &ut->ut_line[4])); + PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, + &ut->ut_line[4])); } else { - PRINTF(("%-*.*s", LINE_WIDTH, LMAX, + PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, ut->ut_line)); } } @@ -504,11 +506,7 @@ retry: /* print idle time */ idle = findidle(ut->ut_line); - if (idle >= 36 * 60) { - PRINTF((dcgettext(NULL, "%2ddays ", LC_TIME), - (idle + 12 * 60) / (24 * 60))); - } else - prttime(idle, " "); + prttime(idle, 8); showtotals(findhash(ut->ut_pid)); } if (fclose(stdout) == EOF) { @@ -537,14 +535,14 @@ showtotals(struct uproc *up) if (lflag) { /* print CPU time for all processes & children */ /* and need to convert clock ticks to seconds first */ - prttime((time_t)jobtime, " "); + prttime((time_t)jobtime, 8); /* print cpu time for interesting process */ /* and need to convert clock ticks to seconds first */ - prttime((time_t)proctime, " "); + prttime((time_t)proctime, 8); } /* what user is doing, current process */ - PRINTF((" %-.32s\n", doing)); + PRINTF(("%-.32s\n", doing)); } /* @@ -646,26 +644,35 @@ findhash(pid_t pid) #define MON (30 * DAY) /* - * prttime prints a time in hours and minutes or minutes and seconds. - * The character string tail is printed at the end, obvious - * strings to pass are "", " ", or "am". + * Prttime prints an elapsed time in hours, minutes, or seconds, + * right-justified with the rightmost column always blank. + * The second argument is the minimum field width. */ static void -prttime(time_t tim, char *tail) +prttime(time_t tim, int width) { - if (tim >= 60) { - PRINTF((dcgettext(NULL, "%3d:%02d", LC_TIME), - (int)tim/60, (int)tim%60)); + char value[36]; + + if (tim >= 36 * 60) { + (void) snprintf(value, sizeof (value), "%d:%02d:%02d", + (int)tim / HR, (int)(tim % HR) / 60, (int)tim % 60); + } else if (tim >= 60) { + (void) snprintf(value, sizeof (value), "%d:%02d", + (int)tim / 60, (int)tim % 60); } else if (tim > 0) { - PRINTF((dcgettext(NULL, " %2d", LC_TIME), (int)tim)); + (void) snprintf(value, sizeof (value), "%d", (int)tim); } else { - PRINTF((" ")); + (void) strcpy(value, "0"); } - PRINTF(("%s", tail)); + width = (width > 2) ? width - 1 : 1; + PRINTF(("%*s ", width, value)); } /* - * prints a 12 hour time given a pointer to a time of day + * Prints the ISO date or time given a pointer to a time of day, + * left-justfied in a 12-character expanding field with the + * rightmost column always blank. + * Includes a dcgettext() override in case a message catalog is needed. */ static void prtat(time_t *time) @@ -675,23 +682,22 @@ prtat(time_t *time) p = localtime(time); if (now - *time <= 18 * HR) { char timestr[50]; + (void) strftime(timestr, sizeof (timestr), - dcgettext(NULL, "%l:%M""%p", LC_TIME), p); - checkampm(timestr); - PRINTF((" %s", timestr)); + dcgettext(NULL, "%T", LC_TIME), p); + PRINTF(("%-11s ", timestr)); } else if (now - *time <= 7 * DAY) { char weekdaytime[20]; (void) strftime(weekdaytime, sizeof (weekdaytime), - dcgettext(NULL, "%a%l%p", LC_TIME), p); - checkampm(weekdaytime); - PRINTF((" %s", weekdaytime)); + dcgettext(NULL, "%a %H:%M", LC_TIME), p); + PRINTF(("%-11s ", weekdaytime)); } else { char monthtime[20]; (void) strftime(monthtime, sizeof (monthtime), - dcgettext(NULL, "%e%b%y", LC_TIME), p); - PRINTF((" %s", monthtime)); + dcgettext(NULL, "%F", LC_TIME), p); + PRINTF(("%-11s ", monthtime)); } } @@ -738,15 +744,3 @@ clnarglist(char *arglist) } } } - -/* replaces all occurences of AM/PM with am/pm */ -static void -checkampm(char *str) -{ - char *ampm; - while ((ampm = strstr(str, "AM")) != NULL || - (ampm = strstr(str, "PM")) != NULL) { - *ampm = tolower(*ampm); - *(ampm+1) = tolower(*(ampm+1)); - } -} diff --git a/usr/src/cmd/whodo/whodo.c b/usr/src/cmd/whodo/whodo.c index 2def679f94..80a781b7b7 100644 --- a/usr/src/cmd/whodo/whodo.c +++ b/usr/src/cmd/whodo/whodo.c @@ -77,7 +77,7 @@ /* Print minimum field widths. */ #define LOGIN_WIDTH 8 -#define LINE_WIDTH 12 +#define LINE_WIDTH 8 #define DIV60(t) ((t+30)/60) /* x/60 rounded */ @@ -133,9 +133,8 @@ static void showproc(struct uproc *); static void showtotals(struct uproc *); static void calctotals(struct uproc *); static char *getty(dev_t); -static void prttime(time_t, char *); +static void prttime(time_t, int); static void prtat(time_t *); -static void checkampm(char *); static char *prog; static int header = 1; /* true if -h flag: don't print heading */ @@ -273,7 +272,7 @@ main(int argc, char *argv[]) mins = uptime / 60; (void) printf(dcgettext(NULL, - " up %d day(s), %d hr(s), " + "up %d day(s), %d hr(s), " "%d min(s)", LC_TIME), days, hrs, mins); } @@ -282,8 +281,9 @@ main(int argc, char *argv[]) ut = utmpbegin; /* rewind utmp data */ (void) printf(dcgettext(NULL, " %d user(s)\n", LC_TIME), nusers); - (void) printf(dcgettext(NULL, "User tty " - "login@ idle JCPU PCPU what\n", LC_TIME)); + (void) printf(dcgettext(NULL, "User tty " + "login@ idle JCPU PCPU what\n", + LC_TIME)); } else { /* standard whodo header */ char date_buf[100]; @@ -291,7 +291,7 @@ main(int argc, char *argv[]) * print current time and date */ (void) strftime(date_buf, sizeof (date_buf), - dcgettext(NULL, "%C", LC_TIME), localtime(&now)); + "%c", localtime(&now)); (void) printf("%s\n", date_buf); /* @@ -474,7 +474,7 @@ retry: ut->ut_name); /* print tty user is on */ - (void) printf("%-*.*s", LINE_WIDTH, (int)LMAX, + (void) printf("%-*.*s ", LINE_WIDTH, (int)LMAX, ut->ut_line); /* print when the user logged in */ @@ -483,11 +483,7 @@ retry: /* print idle time */ idle = findidle(ut->ut_line); - if (idle >= 36 * 60) - (void) printf(dcgettext(NULL, "%2ddays ", - LC_TIME), (idle + 12 * 60) / (24 * 60)); - else - prttime(idle, " "); + prttime(idle, 8); showtotals(findhash((pid_t)ut->ut_pid)); } else { /* standard whodo format */ tim = ut->ut_xtime; @@ -562,14 +558,14 @@ showtotals(struct uproc *up) /* print CPU time for all processes & children */ /* and need to convert clock ticks to seconds first */ - prttime((time_t)jobtime, " "); + prttime((time_t)jobtime, 8); /* print cpu time for interesting process */ /* and need to convert clock ticks to seconds first */ - prttime((time_t)proctime, " "); + prttime((time_t)proctime, 8); /* what user is doing, current process */ - (void) printf(" %-.32s\n", doing); + (void) printf("%-.32s\n", doing); } /* @@ -736,54 +732,63 @@ findhash(pid_t pid) #define HR (60 * 60) #define DAY (24 * HR) #define MON (30 * DAY) +#define PRINTF(a) (void) printf a /* - * prints a time in hours and minutes or minutes and seconds. - * The character string 'tail' is printed at the end, obvious - * strings to pass are "", " ", or "am". + * Prttime prints an elapsed time in hours, minutes, or seconds, + * right-justified with the rightmost column always blank. + * The second argument is the minimum field width. */ static void -prttime(time_t tim, char *tail) +prttime(time_t tim, int width) { - if (tim >= 60) - (void) printf(dcgettext(NULL, "%3d:%02d", LC_TIME), - (int)tim/60, (int)tim%60); - else if (tim > 0) - (void) printf(dcgettext(NULL, " %2d", LC_TIME), (int)tim); - else - (void) printf(" "); - (void) printf("%s", tail); + char value[36]; + + if (tim >= 36 * 60) { + (void) snprintf(value, sizeof (value), "%d:%02d:%02d", + (int)tim / HR, (int)(tim % HR) / 60, (int)tim % 60); + } else if (tim >= 60) { + (void) snprintf(value, sizeof (value), "%d:%02d", + (int)tim / 60, (int)tim % 60); + } else if (tim > 0) { + (void) snprintf(value, sizeof (value), "%d", (int)tim); + } else { + (void) strcpy(value, "0"); + } + width = (width > 2) ? width - 1 : 1; + PRINTF(("%*s ", width, value)); } - /* - * prints a 12 hour time given a pointer to a time of day + * Prints the ISO date or time given a pointer to a time of day, + * left-justfied in a 12-character expanding field with the + * rightmost column always blank. + * Includes a dcgettext() override in case a message catalog is needed. */ static void prtat(time_t *time) { - struct tm *p; + struct tm *p; p = localtime(time); if (now - *time <= 18 * HR) { char timestr[50]; + (void) strftime(timestr, sizeof (timestr), - dcgettext(NULL, " %l:%M""%p", LC_TIME), p); - checkampm(timestr); - (void) printf("%s", timestr); + dcgettext(NULL, "%T", LC_TIME), p); + PRINTF(("%-11s ", timestr)); } else if (now - *time <= 7 * DAY) { char weekdaytime[20]; (void) strftime(weekdaytime, sizeof (weekdaytime), - dcgettext(NULL, "%a%l%p", LC_TIME), p); - checkampm(weekdaytime); - (void) printf(" %s", weekdaytime); + dcgettext(NULL, "%a %H:%M", LC_TIME), p); + PRINTF(("%-11s ", weekdaytime)); } else { char monthtime[20]; (void) strftime(monthtime, sizeof (monthtime), - dcgettext(NULL, "%e%b%y", LC_TIME), p); - (void) printf(" %s", monthtime); + dcgettext(NULL, "%F", LC_TIME), p); + PRINTF(("%-11s ", monthtime)); } } @@ -830,15 +835,3 @@ clnarglist(char *arglist) } } } - -/* replaces all occurences of AM/PM with am/pm */ -static void -checkampm(char *str) -{ - char *ampm; - while ((ampm = strstr(str, "AM")) != NULL || - (ampm = strstr(str, "PM")) != NULL) { - *ampm = tolower(*ampm); - *(ampm+1) = tolower(*(ampm+1)); - } -} diff --git a/usr/src/man/man1/w.1 b/usr/src/man/man1/w.1 index c05c275406..7803ee2f49 100644 --- a/usr/src/man/man1/w.1 +++ b/usr/src/man/man1/w.1 @@ -1,9 +1,10 @@ '\" te +.\" Copyright (c) 2013 Gary Mills .\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved. .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH W 1 "Mar 19, 2004" +.TH W 1 "Dec 15, 2013" .SH NAME w \- display information about currently logged-in users .SH SYNOPSIS @@ -22,12 +23,17 @@ system, and the average number of jobs in the run queue over the last 1, 5 and 15 minutes. .sp .LP -The fields displayed are: the user's login name, the name of the tty the user -is on, the time of day the user logged on (in \fIhours:minutes\fR), the idle -time\(emthat is, the number of minutes since the user last typed anything (in -\fIhours:minutes\fR), the \fBCPU\fR time used by all processes and their -children on that terminal (in \fIminutes:seconds\fR), the \fBCPU\fR time used -by the currently active processes (in \fIminutes:seconds\fR), and the name and +The fields displayed are: the user's login name, +the name of the tty the user is on, +the time of day the user logged on (in ISO time format, weekday name +and \fIhours:minutes\fR, or ISO date format), the idle +time\(emthat is, the number of minutes since the user last typed anything +(in \fIhours:minutes:seconds\fR), +the \fBCPU\fR time used by all processes and their +children on that terminal (in \fIhours:minutes:seconds\fR), +the \fBCPU\fR time used +by the currently active processes (in \fIhours:minutes:seconds\fR), +and the name and arguments of the current process. .SH OPTIONS .sp diff --git a/usr/src/man/man1m/whodo.1m b/usr/src/man/man1m/whodo.1m index d2df2977d2..7827704d0e 100644 --- a/usr/src/man/man1m/whodo.1m +++ b/usr/src/man/man1m/whodo.1m @@ -1,10 +1,11 @@ '\" te +.\" Copyright (c) 2013 Gary Mills .\" Copyright (c) 2001 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 1989 AT&T .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH WHODO 1M "Jun 18, 2003" +.TH WHODO 1M "Dec 15, 2013" .SH NAME whodo \- who is doing what .SH SYNOPSIS @@ -48,13 +49,16 @@ Suppress the heading. .ad .RS 6n Produce a long form of output. The fields displayed are: the user's login name, -the name of the tty the user is on, the time of day the user logged in (in -\fIhours\fR\fB:\fR\fIminutes\fR), the idle time \(em that is, the time since -the user last typed anything (in \fIhours\fR\fB:\fR\fIminutes\fR), the CPU time -used by all processes and their children on that terminal (in -\fIminutes\fR\fB:\fR\fIseconds\fR), the CPU time used by the currently active -processes (in \fIminutes\fR\fB:\fR\fIseconds\fR), and the name and arguments of -the current process. +the name of the tty the user is on, the time of day the user logged in +(in ISO time format, weekday name and \fIhours\fR\fB:\fR\fIminutes\fR, +or ISO date format), +the idle time \(em that is, the time since the user last typed anything +(in \fIhours\fR\fB:\fR\fIminutes\fR\fB:\fR\fIseconds\fR), +the CPU time used by all processes and their children on that terminal +(in \fIhours\fR\fB:\fR\fIminutes\fR\fB:\fR\fIseconds\fR), +the CPU time used by the currently active processes +(in \fIhours\fR\fB:\fR\fIminutes\fR\fB:\fR\fIseconds\fR), +and the name and arguments of the current process. .RE .SH EXAMPLES -- 2.11.4.GIT