From abd9e0f6e228a581930a7c5b5cb64385764bf2d9 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sat, 3 Mar 2012 11:38:52 +0100 Subject: [PATCH 1/5] w: use utmp headers to determine host size as well Completes change in commit ddd15211e0895478f9b6008ff9c26c99d45a1753 Signed-off-by: Sami Kerola --- w.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/w.c b/w.c index da948ba2..f52b951d 100644 --- a/w.c +++ b/w.c @@ -67,10 +67,6 @@ typedef struct utmp utmp_t; # define FROM_STRING "off" #endif -/* Arbitary setting, not too big for the screen, max host size */ -#define HOSTSZ 40 - - /* * This routine is careful since some programs leave utmp strings * unprintable. Always outputs at least 16 chars padded with @@ -249,7 +245,7 @@ static void showinfo(utmp_t * u, int formtype, int maxcmd, int from, char uname[UT_NAMESIZE + 1] = "", tty[5 + UT_LINESIZE + 1] = "/dev/"; const proc_t *best; - for (i = 0; i < sizeof(u->ut_line); i++) + for (i = 0; i < UT_LINESIZE; i++) /* clean up tty if garbled */ if (isalnum(u->ut_line[i]) || (u->ut_line[i] == '/')) tty[i + 5] = u->ut_line[i]; @@ -273,7 +269,7 @@ static void showinfo(utmp_t * u, int formtype, int maxcmd, int from, if (formtype) { printf("%-*.*s%-9.8s", userlen + 1, userlen, uname, u->ut_line); if (from) - print_host(u->ut_host, sizeof u->ut_host, fromlen); + print_host(u->ut_host, UT_HOSTSIZE, fromlen); print_logintime(u->ut_time, stdout); if (*u->ut_line == ':') /* idle unknown for xdm logins */ @@ -293,7 +289,7 @@ static void showinfo(utmp_t * u, int formtype, int maxcmd, int from, printf("%-*.*s%-9.8s", userlen + 1, userlen, u->ut_user, u->ut_line); if (from) - print_host(u->ut_host, sizeof u->ut_host, fromlen); + print_host(u->ut_host, UT_HOSTSIZE, fromlen); if (*u->ut_line == ':') /* idle unknown for xdm logins */ printf(" ?xdm? "); @@ -401,7 +397,7 @@ int main(int argc, char **argv) /* Get user field length from environment */ if ((env_var = getenv("PROCPS_USERLEN")) != NULL) { userlen = atoi(env_var); - if (userlen < 8 || userlen > UT_NAMESIZE) { + if (userlen < 8 || UT_NAMESIZE < userlen) { xwarnx (_("User length environment PROCPS_USERLEN must be between 8 and %zu, ignoring.\n"), UT_NAMESIZE); @@ -411,10 +407,10 @@ int main(int argc, char **argv) /* Get from field length from environment */ if ((env_var = getenv("PROCPS_FROMLEN")) != NULL) { fromlen = atoi(env_var); - if (fromlen < 8 || fromlen > HOSTSZ) { + if (fromlen < 8 || UT_HOSTSIZE < fromlen) { xwarnx (_("from length environment PROCPS_FROMLEN must be between 8 and %d, ignoring\n"), - HOSTSZ); + UT_HOSTSIZE); fromlen = 16; } } From c459346303a428c24f739a83256986f0478b3bc8 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sat, 3 Mar 2012 12:03:40 +0100 Subject: [PATCH 2/5] w: make date string abbreviations nls aware Signed-off-by: Sami Kerola --- w.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/w.c b/w.c index f52b951d..102c6034 100644 --- a/w.c +++ b/w.c @@ -149,14 +149,11 @@ static time_t idletime(const char *restrict const tty) static void print_logintime(time_t logt, FILE * fout) { - /* FIXME: make use of locale, remember strftime() */ - char weekday[][4] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - char month[][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec" - }; + + /* Abbreviated of weekday can be longer than 3 characters, + * see for instance hu_HU. Using 16 is few bytes more than + * enough. */ + char time_str[16]; time_t curt; struct tm *logtm, *curtm; int today; @@ -167,12 +164,15 @@ static void print_logintime(time_t logt, FILE * fout) today = curtm->tm_yday; logtm = localtime(&logt); if (curt - logt > 12 * 60 * 60 && logtm->tm_yday != today) { - if (curt - logt > 6 * 24 * 60 * 60) + if (curt - logt > 6 * 24 * 60 * 60) { + strftime(time_str, sizeof(time_str), "%b", logtm); fprintf(fout, " %02d%3s%02d", logtm->tm_mday, - month[logtm->tm_mon], logtm->tm_year % 100); - else - fprintf(fout, " %3s%02d ", weekday[logtm->tm_wday], + time_str, logtm->tm_year % 100); + } else { + strftime(time_str, sizeof(time_str), "%a", logtm); + fprintf(fout, " %3s%02d ", time_str, logtm->tm_hour); + } } else { fprintf(fout, " %02d:%02d ", logtm->tm_hour, logtm->tm_min); } From 031afacb48962e168e10262458fd1d727ba27cb0 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sat, 3 Mar 2012 12:31:49 +0100 Subject: [PATCH 3/5] w: align header when from lenght is defined Before this commit header and output was not in sync if PROCPS_FROMLEN environment variable where defined. Example of wrong behavior is below where the last four fields which are skewed. $ PROCPS_FROMLEN=18 w -f | cat 12:31:34 up 1:25, 1 user, load average: 0.03, 0.06, 0.06 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT sake tty1 - 11:06 1:25m 3.76s 0.00s xinit /ho[...] Signed-off-by: Sami Kerola --- w.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/w.c b/w.c index 102c6034..db7d75c7 100644 --- a/w.c +++ b/w.c @@ -436,7 +436,7 @@ int main(int argc, char **argv) * headers. Try to keep alignment intact. */ printf(_("%-*s TTY "), userlen, _("USER")); if (from) - printf(_("FROM ")); + printf("%-*s", fromlen - 1, _("FROM")); if (longform) printf(_(" LOGIN@ IDLE JCPU PCPU WHAT\n")); else From ed57504c38941ce2a7620f6b107aec8d855b31c1 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sat, 3 Mar 2012 17:11:45 +0100 Subject: [PATCH 4/5] pmap: add range arguments parsing function Signed-off-by: Sami Kerola --- pmap.c | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/pmap.c b/pmap.c index 1f8b0a0c..b04b521b 100644 --- a/pmap.c +++ b/pmap.c @@ -382,6 +382,28 @@ static int one_proc(proc_t * p) return 0; } +static void range_arguments(char *optarg) +{ + char *arg1; + char *arg2; + + arg1 = xstrdup(optarg); + arg2 = strchr(arg1, ','); + if (arg2) + *arg2 = '\0'; + if (arg2) + ++arg2; + else + arg2 = arg1; + if (arg1 && *arg1) + range_low = STRTOUKL(arg1, &arg1, 16); + if (*arg2) + range_high = STRTOUKL(arg2, &arg2, 16); + if (arg1 && (*arg1 || *arg2)) + xerrx(EXIT_FAILURE, "%s: '%s'", _("failed to parse argument"), + optarg); +} + int main(int argc, char **argv) { unsigned *pidlist; @@ -422,32 +444,7 @@ int main(int argc, char **argv) q_option = 1; break; case 'A': - { - /* FIXME: this should be a function. */ - char *walk = optarg; - char *arg1; - char *arg2; - if (walk[1]) { - arg1 = walk + 1; - walk += strlen(walk) - 1; - } else { - arg1 = *++argv; - if (!arg1) - usage(stderr); - } - arg2 = strchr(arg1, ','); - if (arg2) - *arg2 = '\0'; - if(arg2) ++arg2; - else arg2 = arg1; - - if (arg1 && *arg1) - range_low = STRTOUKL(arg1, &arg1, 16); - if (*arg2) - range_high = STRTOUKL(arg2, &arg2, 16); - if (arg1 && (*arg1 || *arg2)) - usage(stderr); - } + range_arguments(optarg); break; case 'h': usage(stdout); From d5c760ee07d5f2f7d6e5bd78c79e48e74ed276b3 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Sat, 3 Mar 2012 17:51:51 +0100 Subject: [PATCH 5/5] pmap: use only address start to range determination Fix to an edge case. When user defined begining of address range to be at between two allocations the previous allocation which ended to that address was included to printout. After this commit one will see only allocations that are within range definition. $ pmap -A00007f4e0df08000,00007f4e0df08000 895 895: bash 00007f4e0dd08000 2048K ----- /lib/libreadline.so.6.2 00007f4e0df08000 8K r---- /lib/libreadline.so.6.2 total 2056K Signed-off-by: Sami Kerola --- pmap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pmap.c b/pmap.c index b04b521b..3ba1bfe3 100644 --- a/pmap.c +++ b/pmap.c @@ -272,10 +272,10 @@ static int one_proc(proc_t * p) &end, flags, &file_offset, &dev_major, &dev_minor, &inode); - if (start > range_high) - break; - if (end < range_low) + if (end - 1 < range_low) continue; + if (range_high < start) + break; tmp = strchr(mapbuf, '\n'); if (tmp)