svn commit: r337956 - in head: . bin/ls

Rodney W. Grimes freebsd at pdx.rh.CN85.dnsmgr.net
Fri Aug 17 15:24:42 UTC 2018


[ Charset UTF-8 unsupported, converting... ]
> Author: kevans
> Date: Fri Aug 17 04:15:51 2018
> New Revision: 337956
> URL: https://svnweb.freebsd.org/changeset/base/337956
> 
> Log:
>   ls(1): Add --color=when
>   
>   --color may be set to one of: 'auto', 'always', and 'never'.
>   
>   'auto' is the default behavior- output colors only if -G or COLORTERM are

Why different than coreutils ls?   Default for coreutils is none.

>   set, and only if stdout is a tty.
>   
>   'always' is a new behavior- output colors always. termcap(5) will be
>   consulted unless TERM is unset or not a recognized terminal, in which case
>   ls(1) will fall back to explicitly outputting ANSI escape sequences.
>   
>   'never' to turn off any environment variable and -G usage.
Why different than core utils?  Coreutils uses none.

> 
>   Reviewed by:	cem, 0mp (both modulo last-minute manpage changes
>   Differential Revision:	https://reviews.freebsd.org/D16741
> 
> Modified:
>   head/UPDATING
>   head/bin/ls/extern.h
>   head/bin/ls/ls.1
>   head/bin/ls/ls.c
>   head/bin/ls/print.c
>   head/bin/ls/util.c
> 
> Modified: head/UPDATING
> ==============================================================================
> --- head/UPDATING	Fri Aug 17 04:11:10 2018	(r337955)
> +++ head/UPDATING	Fri Aug 17 04:15:51 2018	(r337956)
> @@ -35,9 +35,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
>  	ls(1) now respects the COLORTERM environment variable used in other
>  	systems and software to indicate that a colored terminal is both
>  	supported and desired.  If ls(1) is suddenly emitting colors, they may
> -	be disabled again by removing the unwanted COLORTERM from your
> -	environment.  The ls(1) specific CLICOLOR may not be observed in a
> -	future release.
> +	be disabled again by either removing the unwanted COLORTERM from your
> +	environment, or using `ls --color=never`.  The ls(1) specific CLICOLOR
> +	may not be observed in a future release.
>  
>  20180808:
>  	The default pager for most commands has been changed to "less".  To
> 
> Modified: head/bin/ls/extern.h
> ==============================================================================
> --- head/bin/ls/extern.h	Fri Aug 17 04:11:10 2018	(r337955)
> +++ head/bin/ls/extern.h	Fri Aug 17 04:15:51 2018	(r337956)
> @@ -32,6 +32,8 @@
>   * $FreeBSD$
>   */
>  
> +#include <stdbool.h>
> +
>  int	 acccmp(const FTSENT *, const FTSENT *);
>  int	 revacccmp(const FTSENT *, const FTSENT *);
>  int	 birthcmp(const FTSENT *, const FTSENT *);
> @@ -64,5 +66,12 @@ extern	char	*ansi_bgcol;
>  extern	char	*ansi_coloff;
>  extern	char	*attrs_off;
>  extern	char	*enter_bold;
> +
> +extern int	 colorflag;
> +extern bool	 explicitansi;
> +
> +#define	COLORFLAG_NEVER		0
> +#define	COLORFLAG_AUTO		1
> +#define	COLORFLAG_ALWAYS	2
>  #endif
>  extern int	termwidth;
> 
> Modified: head/bin/ls/ls.1
> ==============================================================================
> --- head/bin/ls/ls.1	Fri Aug 17 04:11:10 2018	(r337955)
> +++ head/bin/ls/ls.1	Fri Aug 17 04:15:51 2018	(r337956)
> @@ -32,7 +32,7 @@
>  .\"     @(#)ls.1	8.7 (Berkeley) 7/29/94
>  .\" $FreeBSD$
>  .\"
> -.Dd August 8, 2018
> +.Dd August 16, 2018
>  .Dt LS 1
>  .Os
>  .Sh NAME
> @@ -41,6 +41,7 @@
>  .Sh SYNOPSIS
>  .Nm
>  .Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,
> +.Op Fl -color Ns = Ns Ar when
>  .Op Fl D Ar format
>  .Op Ar
>  .Sh DESCRIPTION
> @@ -210,6 +211,47 @@ This option is not defined in
>  .St -p1003.1-2001 .
>  .It Fl c
>  Use time when file status was last changed for sorting or printing.
> +.It Fl -color Ns = Ns Ar when
> +Output colored escape sequences based on
> +.Ar when ,
> +which may be set to either
> +.Cm always ,
> +.Cm auto
> +(default), or
> +.Cm never .
> +.Pp
> +.Cm always
> +will make
> +.Nm
> +always output color.
> +If
> +.Ev TERM
> +is unset or set to an invalid terminal, then
> +.Nm
> +will fall back to explicit
> +.Tn ANSI
> +escape sequences without the help of
> +.Xr termcap 5 .
> +.Cm always
> +is the default if
> +.Fl -color
> +is specified without an argument.
> +.Pp
> +.Cm auto
> +will make
> +.Nm
> +output escape sequences based on
> +.Xr termcap 5 ,
> +but only if
> +.Dv stdout
> +is a tty and either the
> +.Fl G
> +flag is specified or the
> +.Ev COLORTERM
> +environment variable is set and not empty.
> +.Pp
> +.Cm never
> +will disable color regardless of environment variables.
>  .It Fl d
>  Directories are listed as plain files (not searched recursively).
>  .It Fl f
> @@ -620,7 +662,10 @@ Colorization
>  is silently disabled if the output is not directed to a terminal
>  unless the
>  .Ev CLICOLOR_FORCE
> -variable is defined.
> +variable is defined or
> +.Fl -color
> +is set to
> +.Dq always .
>  .It Ev CLICOLOR_FORCE
>  Color sequences are normally disabled if the output is not directed to
>  a terminal.
> 
> Modified: head/bin/ls/ls.c
> ==============================================================================
> --- head/bin/ls/ls.c	Fri Aug 17 04:11:10 2018	(r337955)
> +++ head/bin/ls/ls.c	Fri Aug 17 04:15:51 2018	(r337956)
> @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
>  #include <err.h>
>  #include <errno.h>
>  #include <fts.h>
> +#include <getopt.h>
>  #include <grp.h>
>  #include <inttypes.h>
>  #include <limits.h>
> @@ -99,6 +100,16 @@ static void	 display(const FTSENT *, FTSENT *, int);
>  static int	 mastercmp(const FTSENT * const *, const FTSENT * const *);
>  static void	 traverse(int, char **, int);
>  
> +#define	COLOR_OPT	(CHAR_MAX + 1)
> +
> +static const struct option long_opts[] =
> +{
> +#ifdef COLORLS
> +        {"color",       optional_argument,      NULL, COLOR_OPT},
> +#endif
> +        {NULL,          no_argument,            NULL, 0}
> +};
> +
>  static void (*printfcn)(const DISPLAY *);
>  static int (*sortfcn)(const FTSENT *, const FTSENT *);
>  
> @@ -140,10 +151,10 @@ static int f_stream;		/* stream the output, separate w
>  static int f_timesort;		/* sort by time vice name */
>         int f_type;		/* add type character for non-regular files */
>  static int f_whiteout;		/* show whiteout entries */
> -
>  #ifdef COLORLS
> +       int colorflag = COLORFLAG_AUTO;		/* passed in colorflag */
>         int f_color;		/* add type in color for non-regular files */
> -
> +       bool explicitansi;	/* Explicit ANSI sequences, no termcap(5) */
>  char *ansi_bgcol;		/* ANSI sequence to set background colour */
>  char *ansi_fgcol;		/* ANSI sequence to set foreground colour */
>  char *ansi_coloff;		/* ANSI sequence to reset colours */
> @@ -176,6 +187,19 @@ do_color_from_env(void)
>  	    (isatty(STDOUT_FILENO) || getenv("CLICOLOR_FORCE")));
>  }
>  
> +static bool
> +do_color(void)
> +{
> +
> +#ifdef COLORLS
> +	if (colorflag == COLORFLAG_NEVER)
> +		return (false);
> +	else if (colorflag == COLORFLAG_ALWAYS)
> +		return (true);
> +#endif
> +	return (do_color_from_env());
> +}
> +
>  int
>  main(int argc, char *argv[])
>  {
> @@ -187,7 +211,7 @@ main(int argc, char *argv[])
>  #ifdef COLORLS
>  	char termcapbuf[1024];	/* termcap definition buffer */
>  	char tcapbuf[512];	/* capability buffer */
> -	char *bp = tcapbuf;
> +	char *bp = tcapbuf, *term;
>  #endif
>  
>  	(void)setlocale(LC_ALL, "");
> @@ -215,8 +239,9 @@ main(int argc, char *argv[])
>  	fts_options = FTS_PHYSICAL;
>  	if (getenv("LS_SAMESORT"))
>  		f_samesort = 1;
> -	while ((ch = getopt(argc, argv,
> -	    "1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
> +	while ((ch = getopt_long(argc, argv,
> +	    "+1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,", long_opts,
> +	    NULL)) != -1) {
>  		switch (ch) {
>  		/*
>  		 * The -1, -C, -x and -l options all override each other so
> @@ -379,6 +404,19 @@ main(int argc, char *argv[])
>  		case 'y':
>  			f_samesort = 1;
>  			break;
> +#ifdef COLORLS
> +		case COLOR_OPT:
> +			if (optarg == NULL || strcmp(optarg, "always") == 0)
> +				colorflag = COLORFLAG_ALWAYS;
> +			else if (strcmp(optarg, "auto") == 0)
> +				colorflag = COLORFLAG_AUTO;
> +			else if (strcmp(optarg, "never") == 0)
> +				colorflag = COLORFLAG_NEVER;
> +			else
> +				errx(2, "unsupported --color value '%s' (must be always, auto, or never)",
> +				    optarg);
> +			break;
> +#endif
>  		default:
>  		case '?':
>  			usage();
> @@ -391,10 +429,14 @@ main(int argc, char *argv[])
>  	if (!f_listdot && getuid() == (uid_t)0 && !f_noautodot)
>  		f_listdot = 1;
>  
> -	/* Enabling of colours is conditional on the environment. */
> -	if (do_color_from_env())
> +	/*
> +	 * Enabling of colours is conditional on the environment in conjunction
> +	 * with the --color and -G arguments, if supplied.
> +	 */
> +	if (do_color()) {
>  #ifdef COLORLS
> -		if (tgetent(termcapbuf, getenv("TERM")) == 1) {
> +		if ((term = getenv("TERM")) != NULL &&
> +		    tgetent(termcapbuf, term) == 1) {
>  			ansi_fgcol = tgetstr("AF", &bp);
>  			ansi_bgcol = tgetstr("AB", &bp);
>  			attrs_off = tgetstr("me", &bp);
> @@ -408,10 +450,19 @@ main(int argc, char *argv[])
>  				ansi_coloff = tgetstr("oc", &bp);
>  			if (ansi_fgcol && ansi_bgcol && ansi_coloff)
>  				f_color = 1;
> +		} else if (colorflag == COLORFLAG_ALWAYS) {
> +			/*
> +			 * If we're *always* doing color but we don't have
> +			 * a functional TERM supplied, we'll fallback to
> +			 * outputting raw ANSI sequences.
> +			 */
> +			f_color = 1;
> +			explicitansi = true;
>  		}
>  #else
>  		warnx("color support not compiled in");
>  #endif /*COLORLS*/
> +	}
>  
>  #ifdef COLORLS
>  	if (f_color) {
> 
> Modified: head/bin/ls/print.c
> ==============================================================================
> --- head/bin/ls/print.c	Fri Aug 17 04:11:10 2018	(r337955)
> +++ head/bin/ls/print.c	Fri Aug 17 04:15:51 2018	(r337956)
> @@ -73,6 +73,8 @@ static void	printtime(time_t);
>  static int	printtype(u_int);
>  static void	printsize(size_t, off_t);
>  #ifdef COLORLS
> +static void	endcolor_termcap(int);
> +static void	endcolor_ansi(void);
>  static void	endcolor(int);
>  static int	colortype(mode_t);
>  #endif
> @@ -540,7 +542,7 @@ writech(int c)
>  }
>  
>  static void
> -printcolor(Colors c)
> +printcolor_termcap(Colors c)
>  {
>  	char *ansiseq;
>  
> @@ -560,10 +562,53 @@ printcolor(Colors c)
>  }
>  
>  static void
> -endcolor(int sig)
> +printcolor_ansi(Colors c)
>  {
> +
> +	printf("\033[");
> +
> +	if (colors[c].bold)
> +		printf("1");
> +	if (colors[c].num[0] != -1)
> +		printf(";3%d", colors[c].num[0]);
> +	if (colors[c].num[1] != -1)
> +		printf(";4%d", colors[c].num[1]);
> +	printf("m");
> +}
> +
> +static void
> +printcolor(Colors c)
> +{
> +
> +	if (explicitansi)
> +		printcolor_ansi(c);
> +	else
> +		printcolor_termcap(c);
> +}
> +
> +static void
> +endcolor_termcap(int sig)
> +{
> +
>  	tputs(ansi_coloff, 1, sig ? writech : putch);
>  	tputs(attrs_off, 1, sig ? writech : putch);
> +}
> +
> +static void
> +endcolor_ansi(void)
> +{
> +
> +	printf("\33[m");
> +}
> +
> +static void
> +endcolor(int sig)
> +{
> +
> +	if (explicitansi)
> +		endcolor_ansi();
> +	else
> +		endcolor_termcap(sig);
>  }
>  
>  static int
> 
> Modified: head/bin/ls/util.c
> ==============================================================================
> --- head/bin/ls/util.c	Fri Aug 17 04:11:10 2018	(r337955)
> +++ head/bin/ls/util.c	Fri Aug 17 04:15:51 2018	(r337956)
> @@ -227,7 +227,7 @@ usage(void)
>  {
>  	(void)fprintf(stderr,
>  #ifdef COLORLS
> -	"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
> +	"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [--color=when] [-D format]"
>  #else
>  	"usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
>  #endif
> 
> 

-- 
Rod Grimes                                                 rgrimes at freebsd.org


More information about the svn-src-all mailing list