From nobody@FreeBSD.org  Mon Aug 10 20:34:15 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 6675110656A4
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 10 Aug 2009 20:34:15 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 5585E8FC39
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 10 Aug 2009 20:34:15 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n7AKYFAS010688
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 10 Aug 2009 20:34:15 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id n7AKYFZi010687;
	Mon, 10 Aug 2009 20:34:15 GMT
	(envelope-from nobody)
Message-Id: <200908102034.n7AKYFZi010687@www.freebsd.org>
Date: Mon, 10 Aug 2009 20:34:15 GMT
From: Ivan Radovanovic <rivanr@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: ps output depends on terminals column width when piping or redirecting
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         137647
>Category:       bin
>Synopsis:       ps(1) output depends on terminals column width when piping or redirecting
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    brian
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Aug 10 20:40:01 UTC 2009
>Closed-Date:    Thu Jun 03 08:50:08 UTC 2010
>Last-Modified:  Thu Jun 03 08:50:08 UTC 2010
>Originator:     Ivan Radovanovic
>Release:        7.2
>Organization:
>Environment:
FreeBSD azdaja.softwarehood.com 7.2-STABLE FreeBSD 7.2-STABLE #0: Mon Aug  3 17:12:57 CEST 2009     rivan@azdaja.softwarehood.com:/usr/src/sys/i386/compile/Azdaja  i386
>Description:
ps command formats its output according to setting of terminal it is running on even when piped or redirected to a file. This can cause serious confusion when using it in combination with other commands (for example ps -axj | grep opera won't give any output regardless opera browser is running in the example in "how to repeat" section)

>How-To-Repeat:
open xterm, set its width to 40 columns, do
ps -axj > ps.txt
ps.txt will be 40 columns wide

>Fix:
use isatty or stat to determine if ps's output is terminal

>Release-Note:
>Audit-Trail:

From: Michael Gmelin <freebsdusb@bindone.de>
To: Ivan Radovanovic <rivanr@gmail.com>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: misc/137647: ps output depends on terminals column width when
 piping or redirecting
Date: Mon, 10 Aug 2009 22:49:52 +0200

 Try using ps -wwaxj > ps.txt
 
 afaik this is the intended behaviour of ps.
 

From: Justin Hibbits <jrh29@alumni.cwru.edu>
To: bug-followup@freebsd.org, rivanr@gmail.com
Cc:  
Subject: Re: misc/137647: ps output depends on terminals column width when 
	piping or redirecting
Date: Mon, 10 Aug 2009 18:49:57 -0400

 This patch hasn't been tested with every possible tty, but it works
 with xterm, vc, and redirect.  There is one caveat, it breaks "ps aux
 | less", if one wants a simple list.
 (Gmail isn't cooperating, so patch is inline).
 
 ===================================================================
 --- ps.c	(revision 195790)
 +++ ps.c	(working copy)
 @@ -187,6 +187,8 @@
 
  	if ((cols = getenv("COLUMNS")) != NULL && *cols != '\0')
  		termwidth = atoi(cols);
 +	else if (!isatty(STDOUT_FILENO))
 +		termwidth = UNLIMITED;
  	else if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&ws) == -1 &&
  	     ioctl(STDERR_FILENO, TIOCGWINSZ, (char *)&ws) == -1 &&
  	     ioctl(STDIN_FILENO,  TIOCGWINSZ, (char *)&ws) == -1) ||
State-Changed-From-To: open->closed 
State-Changed-By: brian 
State-Changed-When: Tue Aug 25 07:56:45 UTC 2009 
State-Changed-Why:  
I agree with Michael.  ps(1) checks stdout, stderr then stdin to see if 
it's a tty, and if none are will set the width to 79. 

Scripts should either use pgrep or pkill, or else use ps -ww and also 
possibly -o comm or -o command. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=137647 
State-Changed-From-To: closed->open 
State-Changed-By: brian 
State-Changed-When: Tue Aug 25 10:29:16 UTC 2009 
State-Changed-Why:  
On second thoughts, maybe I shouldn't be so quick to declare what 
ps has always done as being correct... 


Responsible-Changed-From-To: freebsd-bugs->brian 
Responsible-Changed-By: brian 
Responsible-Changed-When: Tue Aug 25 10:29:16 UTC 2009 
Responsible-Changed-Why:  
On second thoughts, maybe I shouldn't be so quick to declare what 
ps has always done as being correct... 

http://www.freebsd.org/cgi/query-pr.cgi?pr=137647 

From: Mark Linimon <linimon@lonesome.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/137647: ps(1) output depends on terminals column width
	when piping or redirecting
Date: Tue, 25 Aug 2009 10:22:41 -0500

 ----- Forwarded message from Bruce Evans <brde@optusnet.com.au> -----
 
 From: Bruce Evans <brde@optusnet.com.au>
 To: brian@FreeBSD.org
 Cc: freebsd-bugs@FreeBSD.org, rivanr@gmail.com
 Subject: Re: bin/137647: ps(1) output depends on terminals column width when
 	piping or redirecting
 
 On Tue, 25 Aug 2009 brian@FreeBSD.org wrote:
 > I agree with Michael.  ps(1) checks stdout, stderr then stdin to see if
 > it's a tty, and if none are will set the width to 79.
 >
 > Scripts should either use pgrep or pkill, or else use ps -ww and also
 > possibly -o comm or -o command.
 
 Er, don't you agree with me?  I sent a long reply, including to
 bug-followup, but it isn't in the PR followup :-(.  Summary:
 (1) checking stdin is bogus and is what causes this problem, but I
     can't see a better way to handle cases like "ps | less" where the
     output is redirected but the final output is still to a tty.
 (2) handling of widths is mostly broken, starting with it mostly only
     applying to the last field.
 
 Bruce
 
 ----- End forwarded message -----

From: Mark Linimon <linimon@lonesome.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/137647: ps(1) output depends on terminals column width
	when piping or redirecting
Date: Mon, 7 Sep 2009 10:52:27 -0500

 ----- Forwarded message from Bruce Evans <brde@optusnet.com.au> -----
 
 Date: Wed, 12 Aug 2009 01:18:51 +1000 (EST)
 From: Bruce Evans <brde@optusnet.com.au>
 To: Justin Hibbits <jrh29@alumni.cwru.edu>
 Subject: Re: bin/137647: ps output depends on terminals column width when
  piping or redirecting
 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed
 
 On Mon, 10 Aug 2009, Justin Hibbits wrote:
 
 > This patch hasn't been tested with every possible tty, but it works
 > with xterm, vc, and redirect.  There is one caveat, it breaks "ps aux
 > | less", if one wants a simple list.
 > (Gmail isn't cooperating, so patch is inline).
 >
 > ===================================================================
 > --- ps.c	(revision 195790)
 > +++ ps.c	(working copy)
 > @@ -187,6 +187,8 @@
 >
 >  	if ((cols = getenv("COLUMNS")) != NULL && *cols != '\0')
 >  		termwidth = atoi(cols);
 > +	else if (!isatty(STDOUT_FILENO))
 > +		termwidth = UNLIMITED;
 >  	else if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&ws) == -1 &&
 >  	     ioctl(STDERR_FILENO, TIOCGWINSZ, (char *)&ws) == -1 &&
 >  	     ioctl(STDIN_FILENO,  TIOCGWINSZ, (char *)&ws) == -1) ||
 
 This is a verbose way of removing the bogus ioctls on STDERR_FILENO
 and STDIN_FILENO (good) and changing the default width (when COLUMNS
 is not set) from 79 to UNLIMITED (bad).  The ioctl on STDOUT_FILENO
 already fails when stdout is not a tty, and perhaps in other cases,
 but then the ioctl on STDERR_FILENO sometimes breaks this (not usually,
 since stderr should be redirected if stdout is) and the ioctl on
 STDIN_FILENO usually breaks this (since ps is usually used in interactive
 mode and it is unusual to redirect stdin when redirecting stdout/err).
 
 However, the current terminal's width is still needed for things like
 "ps any | less", and the historical default of 79 is needed for
 compatibility in the non-interactive case, so you cannot simply add
 or remove tty checks or change the default to UNLIMITED.
 
 I don't see any better fix than changing the man page to emphasize that
 the COLUMNS environment variable must be used when the defaults and guesses
 don't work as desired, and to document the defaults and guesses precisely.
 It has apparently always been necessary to set COLUMNS in scripts, so that
 the width doesn't depend on COLUMNS being either unset or non-garbage in
 the environment or on the defaults and guesses.
 
 I see the following slightly broken behaviour involving COLUMNS with an
 old version of bash on an xterm: bash sets COLUMNS, apparently using the
 TIOCGWINSZ ioctl.  It doesn't export it so this doesn't affect ps.  After
 COLUMNS is unset, any window size change sets it again (to the new width).
 
 Some related documentation bugs:
 - the historical default width of 79 is not documented.
 - -w (with a single w) is documented to use 132 columns, but actually uses
    the current width if that is larger than 131 columns, else 131 columns
 - the UNLIMITED width is useful to applications, and is available by
    setting COLUMNS to 0, but this is not documented.  You can get the same
    effect by setting COLUMNS to a preposterously large value.
 - the range of valid values for COLUMNS is not documented.  It happens to
    be {0} and [N(opts)..INT_MAX], where N(opts) is an undocumented positive
    int depending on the format, so preposterously large values are possible.
 
 Some related code bugs:
 - invalid values for COLUMNS are silently accepted.  At least for ps al,
    both negative values and reasonable positive values cause broken
    behaviour.  I think this is because ps ignores COLUMNS for all fields
    except the last one: for ps al, COLUMNS=69 correctly truncates the
    COMMAND string to 1 character, but COLUMNS=68 and COLUMNS=-1 give
    truncation to 84 columns total, quite unlike the default of truncation
    to 79 columns total.
 - the cutoff of 69 for ps al is undocumented.  In FreeBSD-5.2, it was 68
    (also undocumented) due to less bloat in fields before COMMAND.
 - the magic 84 is due to one of the many known bugs in printing of the
    last field: from arguments():
 
 % 	if (STAILQ_NEXT(ve, next_ve) == NULL) {
 % 		/* last field */
 % 		if (termwidth == UNLIMITED) {
 % 			(void)printf("%s", vis_args);
 
 This normally gives 131 columns.
 
 % 		} else {
 % 			left = termwidth - (totwidth - v->width);
 
 This is <= 0 when COLUMNS is too small to work.
 
 % 			if (left < 1) /* already wrapped, just use std width */
 % 				left = v->width;
 
 Then we use the default width for COMMAND, and happen to reach 84 columns
 instead of the normal default of 79, even when we asked for < 79 and 79
 would work.
 
 ps al gives a simple example of this broken behaviour.  In general, the
 limit for COLUMNS depends on the options.
 
 % 			for (cp = vis_args; --left >= 0 && *cp != '\0';)
 % 				(void)putchar(*cp++);
 % 		}
 % 	} else {
 % 		(void)printf("%-*.*s", v->width, v->width, vis_args);
 
 This is used for all fields except the last.  It always uses the full
 field width, so COLUMNS and the window size are almost useless for
 controlling the total number of columns.  Truncation works reasonably
 for the COMMAND column but not for most columns, so the special handling
 for the last column is wrong for formats that don't put the COMMAND
 column last.  I think integer formats just don't get truncated.  A
 related problem is that it is hard or impossible to print the full
 COMMAND column unless it is printed last.  E.g., "ps -o args" works
 right, but "ps -o args,pid" truncates the args and adding -w makes no
 difference.
 
 % 	}
 
 Bruce
 
 
 ----- End forwarded message -----
State-Changed-From-To: open->closed 
State-Changed-By: brian 
State-Changed-When: Thu Jun 3 08:47:46 UTC 2010 
State-Changed-Why:  
The world isn't ready to change this behaviour.  The workaround is to always 
use 'ww'! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=137647 
>Unformatted:
