NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: standards/18257: POSIX.2-1992: ps(1)'s TIME column has the wrong format
The following reply was made to PR standards/18257; it has been noted by GNATS.
From: Julian Fagir <gnrp%komkon2.de@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: M.Drochner%fz-juelich.de@localhost
Subject: Re: standards/18257: POSIX.2-1992: ps(1)'s TIME column has the
wrong format
Date: Wed, 15 Feb 2012 04:40:56 +0100
--MP_/igSg+bg1Z7cKc=gCCoJxKOX
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Hi,
> > You could either introduce another keyword - e.g. pcputime or ptime (p for
> > precision) to display them again - or dump this proposal and be non-posix
> > compliant or dump the precision and be posix-compliant.
>
> Imo it would make most sense to keep the traditional display if
> called with BSD syntax ("ps ax"), and be POSIX compliant if
> called with SYSV/POSIX syntax ("ps -ef").
> As long as we don't support POSIX at the command line there is
> no need to have the display strictly POSIX compliant.
ok, so what about the attached patches?
They have [[dd-]hh:]mm:ss for etime in any case, [hh:]mm:ss for time in POSIX
case and [hh:]mm:ss.pp for time in BSD case.
Regards, Julian
--MP_/igSg+bg1Z7cKc=gCCoJxKOX
Content-Type: text/x-patch
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=extern.h.diff
--- bin/ps/extern.h
+++ bin/ps/extern.h
@@ -38,10 +38,11 @@
extern double ccpu;
extern int eval, fscale, mempages, nlistread, rawcpu, maxslp, uspace;
extern int sumrusage, termwidth, totwidth;
extern int needenv, needcomm, commandonly;
+extern int bsdpsopts;
extern uid_t myuid;
extern kvm_t *kd;
extern VAR var[];
extern VARLIST displaylist;
extern VARLIST sortlist;
@@ -76,10 +77,11 @@
void pcpu(void *, VARENT *, int);
void pmem(void *, VARENT *, int);
void pnice(void *, VARENT *, int);
void pri(void *, VARENT *, int);
void printheader(void);
+void printtime(int, int, int, int, int, int, int);
void putimeval(void *, VARENT *, int);
void pvar(void *, VARENT *, int);
void rgname(void *, VARENT *, int);
void rssize(void *, VARENT *, int);
void runame(void *, VARENT *, int);
@@ -94,5 +96,6 @@
void ucomm(void *, VARENT *, int);
void uname(void *, VARENT *, int);
void uvar(void *, VARENT *, int);
void vsize(void *, VARENT *, int);
void wchan(void *, VARENT *, int);
+int widthtime(int, int, int, int, int, int);
--MP_/igSg+bg1Z7cKc=gCCoJxKOX
Content-Type: text/x-patch
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=print.c.diff
--- bin/ps/print.c
+++ bin/ps/print.c
@@ -102,10 +102,12 @@
static time_t now;
#define min(a,b) ((a) <= (b) ? (a) : (b))
+#define PHOURS 0x01
+
static int
iwidth(u_int64_t v)
{
u_int64_t nlim, lim;
int w = 1;
@@ -846,14 +848,14 @@
}
void
elapsed(void *arg, VARENT *ve, int mode)
{
+ int32_t origseconds, secs, mins, hours, days;
struct kinfo_proc2 *k;
VAR *v;
- int32_t origseconds, secs, mins, hours, days;
- int fmtlen, printed_something;
+ int fmtlen;
k = arg;
v = ve->var;
if (k->p_uvalid == 0) {
origseconds = 0;
@@ -878,66 +880,122 @@
mins %= MINSPERHOUR;
days = hours / HOURSPERDAY;
hours %= HOURSPERDAY;
if (mode == WIDTHMODE) {
- if (origseconds == 0)
- /* non-zero so fmtlen is calculated at least once */
- origseconds = 1;
-
if (origseconds > v->longestp) {
v->longestp = origseconds;
-
- if (days > 0) {
- /* +9 for "-hh:mm:ss" */
- fmtlen = iwidth(days) + 9;
- } else if (hours > 0) {
- /* +6 for "mm:ss" */
- fmtlen = iwidth(hours) + 6;
- } else {
- /* +3 for ":ss" */
- fmtlen = iwidth(mins) + 3;
- }
-
+ fmtlen = widthtime(days, hours, mins, secs, 0, 0);
+ if (fmtlen > v->width)
+ v->width = fmtlen;
+ }
+ } else {
+ (void)printtime(days, hours, mins, secs, 0, v->width, 0);
+ }
+}
+
+void
+cputime(void *arg, VARENT *ve, int mode)
+{
+ int32_t psecs, secs, mins, hours, days;
+ struct kinfo_proc2 *k;
+ VAR *v;
+ int fmtlen;
+
+ k = arg;
+ v = ve->var;
+ /*
+ * This counts time spent handling interrupts. We could
+ * fix this, but it is not 100% trivial (and interrupt
+ * time fractions only work on the sparc anyway). XXX
+ */
+ secs = k->p_rtime_sec;
+ psecs = k->p_rtime_usec;
+ if (sumrusage) {
+ secs += k->p_uctime_sec;
+ psecs += k->p_uctime_usec;
+ }
+ /*
+ * round and scale to 100's
+ */
+ psecs = (psecs + 5000) / 10000;
+ secs += psecs / 100;
+ psecs = psecs % 100;
+
+ mins = secs / SECSPERMIN;
+ secs %= SECSPERMIN;
+ hours = mins / MINSPERHOUR;
+ mins %= MINSPERHOUR;
+ days = hours / HOURSPERDAY;
+ hours %= HOURSPERDAY;
+
+ if (mode == WIDTHMODE) {
+ if (secs > v->longestp) {
+ v->longestp = secs;
+ fmtlen = widthtime(days, hours, mins, secs, psecs,
+ PHOURS);
if (fmtlen > v->width)
v->width = fmtlen;
}
} else {
- printed_something = 0;
- fmtlen = v->width;
-
- if (days > 0) {
- (void)printf("%*d", fmtlen - 9, days);
- printed_something = 1;
- } else if (fmtlen > 9) {
- (void)printf("%*s", fmtlen - 9, "");
- }
- if (fmtlen > 9)
- fmtlen = 9;
-
- if (printed_something) {
- (void)printf("-%.*d", fmtlen - 7, hours);
- printed_something = 1;
- } else if (hours > 0) {
- (void)printf("%*d", fmtlen - 6, hours);
- printed_something = 1;
- } else if (fmtlen > 6) {
- (void)printf("%*s", fmtlen - 6, "");
- }
- if (fmtlen > 6)
- fmtlen = 6;
-
- /* Don't need to set fmtlen or printed_something any more... */
- if (printed_something) {
- (void)printf(":%.*d", fmtlen - 4, mins);
- } else if (mins > 0) {
- (void)printf("%*d", fmtlen - 3, mins);
- } else if (fmtlen > 3) {
- (void)printf("%*s", fmtlen - 3, "0");
- }
-
- (void)printf(":%.2d", secs);
+ (void)printtime(days, hours, mins, secs, psecs, v->width,
PHOURS);
+ }
+}
+
+/*
+ * We have three different outputs:
+ * 1. BSD options time:
+ * hh:mm:ss.pp
+ * 2. POSIX options time:
+ * [dd-]hh:mm:ss
+ * 3. BSD and POSIX options etime:
+ * [[dd-]hh:]mm:ss
+ */
+int
+widthtime(int days, int hours, int mins, int secs, int psecs, int printmod)
+{
+ int fmtlen;
+
+ if (bsdpsopts && (printmod & PHOURS)) { /* BSD opts time */
+ if (hours > 0)
+ fmtlen = iwidth(hours + days * HOURSPERDAY) + 9;
+ else
+ fmtlen = iwidth(mins) + 6;
+ } else { /* Any opts etime + POSIX opts time */
+ if (days > 0)
+ fmtlen = iwidth(days) + 9;
+ else if (hours > 0 || (printmod & PHOURS)) /* POSIX opts time */
+ fmtlen = 8;
+ else
+ fmtlen = 5;
+ }
+
+ return fmtlen;
+}
+
+void
+printtime(int days, int hours, int mins, int secs, int psecs, int fmtlen,
+ int printmod)
+{
+ if (bsdpsopts && (printmod & PHOURS)) { /* BSD opts time */
+ if (hours > 0)
+ (void)printf("%*d:%.2d:%.2d.%.2d", fmtlen - 9,
+ hours + days * HOURSPERDAY,
+ mins, secs, psecs);
+ else
+ (void)printf("%*d:%.2d.%.2d", fmtlen - 6, mins,
+ secs, psecs);
+ } else { /* Any opts etime + POSIX opts time */
+ if (days > 0)
+ (void)printf("%*d-%.2d:%.2d:%.2d", fmtlen - 9,
+ days, hours, mins, secs);
+ else if (hours > 0 || printmod & PHOURS) /* POSIX opts time */
+ (void)printf("%*.2d:%.2d:%.2d", fmtlen - 6,
+ hours, mins, secs);
+ else
+ (void)printf("%*.2d:%.2d", fmtlen - 3, mins,
+ secs);
}
}
void
wchan(void *arg, VARENT *ve, int mode)
@@ -1010,64 +1068,10 @@
VAR *v;
l = arg;
v = ve->var;
intprintorsetwidth(v, l->l_cpuid, mode);
-}
-
-void
-cputime(void *arg, VARENT *ve, int mode)
-{
- struct kinfo_proc2 *k;
- VAR *v;
- int32_t secs;
- int32_t psecs; /* "parts" of a second. first micro, then centi */
- int fmtlen;
-
- k = arg;
- v = ve->var;
-
- /*
- * This counts time spent handling interrupts. We could
- * fix this, but it is not 100% trivial (and interrupt
- * time fractions only work on the sparc anyway). XXX
- */
- secs = k->p_rtime_sec;
- psecs = k->p_rtime_usec;
- if (sumrusage) {
- secs += k->p_uctime_sec;
- psecs += k->p_uctime_usec;
- }
- /*
- * round and scale to 100's
- */
- psecs = (psecs + 5000) / 10000;
- secs += psecs / 100;
- psecs = psecs % 100;
-
- if (mode == WIDTHMODE) {
- /*
- * Ugg, this is the only field where a value of 0 is longer
- * than the column title.
- * Use SECSPERMIN, because secs is divided by that when
- * passed to iwidth().
- */
- if (secs == 0)
- secs = SECSPERMIN;
-
- if (secs > v->longestp) {
- v->longestp = secs;
- /* "+6" for the ":%02ld.%02ld" in the printf() below */
- fmtlen = iwidth(secs / SECSPERMIN) + 6;
- if (fmtlen > v->width)
- v->width = fmtlen;
- }
- } else {
- (void)printf("%*ld:%02ld.%02ld", v->width - 6,
- (long)(secs / SECSPERMIN), (long)(secs % SECSPERMIN),
- (long)psecs);
- }
}
double
getpcpu(k)
const struct kinfo_proc2 *k;
--MP_/igSg+bg1Z7cKc=gCCoJxKOX
Content-Type: text/x-patch
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=ps.1.diff
--- bin/ps/ps.1
+++ bin/ps/ps.1
@@ -638,10 +638,15 @@
.It Ar tdev
control terminal device number
.It Ar time
accumulated CPU time, user + system (alias
.Ar cputime )
+in the format
+.Li [dd-]hh:mm:ss
+if you use POSIX-style options or
+.Li [hh:]mm:ss.pp
+if you use BSD-style options
.It Ar tpgid
control terminal process group
.Tn ID
.It Ar tsess
control terminal session pointer
--MP_/igSg+bg1Z7cKc=gCCoJxKOX
Content-Type: text/x-patch
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=ps.c.diff
--- bin/ps/ps.c
+++ bin/ps/ps.c
@@ -109,10 +109,11 @@
struct kinfo_proc2 *kinfo;
struct varlist displaylist = SIMPLEQ_HEAD_INITIALIZER(displaylist);
struct varlist sortlist = SIMPLEQ_HEAD_INITIALIZER(sortlist);
+int bsdpsopts; /* set to 1 when using BSD options */
int eval; /* exit value */
int rawcpu; /* -C */
int sumrusage; /* -S */
int termwidth; /* width of screen (0 == infinity) */
int totwidth; /* calculated width of requested variables */
@@ -696,12 +697,14 @@
if ((newopts = ns = malloc(len + 3)) == NULL)
err(1, NULL);
/*
* options begin with '-'
*/
- if (*s != '-')
+ if (*s != '-') {
*ns++ = '-'; /* add option flag */
+ bsdpsopts = 1;
+ }
/*
* gaze to end of argv[1]
*/
cp = s + len - 1;
/*
--MP_/igSg+bg1Z7cKc=gCCoJxKOX--
Home |
Main Index |
Thread Index |
Old Index