summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base64.c10
-rw-r--r--src/basename.c6
-rw-r--r--src/cat.c60
-rw-r--r--src/chcon.c6
-rw-r--r--src/chgrp.c6
-rw-r--r--src/chmod.c6
-rw-r--r--src/chown-core.c2
-rw-r--r--src/chown-core.h2
-rw-r--r--src/chown.c6
-rw-r--r--src/chroot.c78
-rw-r--r--src/cksum.c8
-rw-r--r--src/comm.c12
-rw-r--r--src/copy.c301
-rw-r--r--src/copy.h4
-rw-r--r--src/coreutils-arch.c11
-rw-r--r--src/coreutils-dir.c11
-rw-r--r--src/coreutils-vdir.c11
-rw-r--r--src/coreutils.c29
-rw-r--r--src/cp-hash.c2
-rw-r--r--src/cp.c10
-rw-r--r--src/csplit.c23
-rw-r--r--src/cut.c11
-rw-r--r--src/date.c44
-rwxr-xr-xsrc/dcgen2
-rw-r--r--src/dd.c291
-rw-r--r--src/df.c82
-rw-r--r--src/dircolors.c8
-rw-r--r--src/dircolors.h9
-rw-r--r--src/dircolors.hin9
-rw-r--r--src/dirname.c6
-rw-r--r--src/du.c37
-rw-r--r--src/echo.c10
-rw-r--r--src/env.c14
-rw-r--r--src/expand.c8
-rw-r--r--src/expr.c6
-rw-r--r--src/extent-scan.c4
-rw-r--r--src/extent-scan.h10
-rw-r--r--src/extract-magic2
-rw-r--r--src/factor.c122
-rw-r--r--src/fiemap.h2
-rw-r--r--src/find-mount-point.c2
-rw-r--r--src/find-mount-point.h2
-rw-r--r--src/fmt.c29
-rw-r--r--src/fold.c23
-rw-r--r--src/fs-is-local.h1
-rw-r--r--src/fs.h1
-rw-r--r--src/getlimits.c6
-rw-r--r--src/group-list.c2
-rw-r--r--src/group-list.h2
-rw-r--r--src/groups.c6
-rw-r--r--src/head.c187
-rw-r--r--src/hostid.c6
-rw-r--r--src/hostname.c6
-rw-r--r--src/id.c6
-rw-r--r--src/install.c6
-rw-r--r--src/ioblksize.h2
-rw-r--r--src/join.c18
-rw-r--r--src/kill.c14
-rw-r--r--src/libstdbuf.c4
-rw-r--r--src/link.c6
-rw-r--r--src/ln.c6
-rw-r--r--src/local.mk25
-rw-r--r--src/logname.c19
-rw-r--r--src/longlong.h208
-rw-r--r--src/ls.c103
-rw-r--r--src/make-prime-list.c11
-rw-r--r--src/md5sum.c19
-rw-r--r--src/mkdir.c25
-rw-r--r--src/mkfifo.c6
-rw-r--r--src/mknod.c8
-rw-r--r--src/mktemp.c6
-rw-r--r--src/mv.c8
-rw-r--r--src/nice.c16
-rw-r--r--src/nl.c54
-rw-r--r--src/nohup.c51
-rw-r--r--src/nproc.c14
-rw-r--r--src/numfmt.c552
-rw-r--r--src/od.c43
-rw-r--r--src/operand2sig.c2
-rw-r--r--src/operand2sig.h2
-rw-r--r--src/paste.c14
-rw-r--r--src/pathchk.c6
-rw-r--r--src/pinky.c9
-rw-r--r--src/pr.c140
-rw-r--r--src/printenv.c6
-rw-r--r--src/printf.c8
-rw-r--r--src/prog-fprintf.c2
-rw-r--r--src/prog-fprintf.h2
-rw-r--r--src/ptx.c22
-rw-r--r--src/pwd.c8
-rw-r--r--src/readlink.c6
-rw-r--r--src/realpath.c6
-rw-r--r--src/relpath.c2
-rw-r--r--src/relpath.h2
-rw-r--r--src/remove.c2
-rw-r--r--src/remove.h2
-rw-r--r--src/rm.c22
-rw-r--r--src/rmdir.c6
-rw-r--r--src/runcon.c14
-rw-r--r--src/selinux.c2
-rw-r--r--src/selinux.h2
-rw-r--r--src/seq.c123
-rw-r--r--src/shred.c43
-rw-r--r--src/shuf.c34
-rw-r--r--src/single-binary.mk212
-rw-r--r--src/sleep.c6
-rw-r--r--src/sort.c11
-rw-r--r--src/split.c365
-rw-r--r--src/stat.c11
-rw-r--r--src/stdbuf.c20
-rw-r--r--src/stty.c428
-rw-r--r--src/sum.c15
-rw-r--r--src/sync.c191
-rw-r--r--src/system.h74
-rw-r--r--src/tac-pipe.c2
-rw-r--r--src/tac.c90
-rw-r--r--src/tail.c377
-rw-r--r--src/tee.c95
-rw-r--r--src/test.c12
-rw-r--r--src/timeout.c31
-rw-r--r--src/touch.c6
-rw-r--r--src/tr.c10
-rw-r--r--src/true.c6
-rw-r--r--src/truncate.c42
-rw-r--r--src/tsort.c14
-rw-r--r--src/tty.c6
-rw-r--r--src/uname.c6
-rw-r--r--src/unexpand.c8
-rw-r--r--src/uniq.c12
-rw-r--r--src/unlink.c6
-rw-r--r--src/uptime.c6
-rw-r--r--src/users.c6
-rw-r--r--src/wc.c112
-rw-r--r--src/who.c10
-rw-r--r--src/whoami.c17
-rw-r--r--src/yes.c62
136 files changed, 3492 insertions, 2048 deletions
diff --git a/src/base64.c b/src/base64.c
index b0656043..ec3fe072 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -1,5 +1,5 @@
/* Base64 encode/decode strings or files.
- Copyright (C) 2004-2014 Free Software Foundation, Inc.
+ Copyright (C) 2004-2015 Free Software Foundation, Inc.
This file is part of Base64.
@@ -62,6 +62,7 @@ Usage: %s [OPTION]... [FILE]\n\
Base64 encode or decode FILE, or standard input, to standard output.\n\
"), program_name);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -75,15 +76,12 @@ Base64 encode or decode FILE, or standard input, to standard output.\n\
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
\n\
-With no FILE, or when FILE is -, read standard input.\n"), stdout);
- fputs (_("\
-\n\
The data are encoded as described for the base64 alphabet in RFC 3548.\n\
When decoding, the input may contain newlines in addition to the bytes of\n\
the formal base64 alphabet. Use --ignore-garbage to attempt to recover\n\
from any other non-alphabet bytes in the encoded stream.\n"),
stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
@@ -321,5 +319,5 @@ main (int argc, char **argv)
error (EXIT_FAILURE, errno, "%s", infile);
}
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/basename.c b/src/basename.c
index 95215399..71f75582 100644
--- a/src/basename.c
+++ b/src/basename.c
@@ -1,5 +1,5 @@
/* basename -- strip directory and suffix from file names
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -73,7 +73,7 @@ Examples:\n\
%s -a any/str1 any/str2 -> \"str1\" followed by \"str2\"\n\
"),
program_name, program_name, program_name, program_name);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -185,5 +185,5 @@ main (int argc, char **argv)
perform_basename (argv[optind],
optind + 2 == argc ? argv[optind + 1] : NULL, use_nuls);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/cat.c b/src/cat.c
index 8aef79fa..948f1341 100644
--- a/src/cat.c
+++ b/src/cat.c
@@ -1,5 +1,5 @@
/* cat -- concatenate files and print on the standard output.
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -90,7 +90,12 @@ Usage: %s [OPTION]... [FILE]...\n\
"),
program_name);
fputs (_("\
-Concatenate FILE(s), or standard input, to standard output.\n\
+Concatenate FILE(s) to standard output.\n\
+"), stdout);
+
+ emit_stdin_note ();
+
+ fputs (_("\
\n\
-A, --show-all equivalent to -vET\n\
-b, --number-nonblank number nonempty output lines, overrides -n\n\
@@ -107,10 +112,6 @@ Concatenate FILE(s), or standard input, to standard output.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
-With no FILE, or when FILE is -, read standard input.\n\
-"), stdout);
printf (_("\
\n\
Examples:\n\
@@ -118,7 +119,7 @@ Examples:\n\
%s Copy standard input to standard output.\n\
"),
program_name, program_name);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -239,7 +240,7 @@ cat (
/* Pointer to the next character in the input buffer. */
char *bpin;
- /* Pointer to the first non-valid byte in the input buffer, i.e. the
+ /* Pointer to the first non-valid byte in the input buffer, i.e., the
current end of the buffer. */
char *eob;
@@ -365,7 +366,7 @@ cat (
/* It was a real (not a sentinel) newline. */
/* Was the last line empty?
- (i.e. have two or more consecutive newlines been read?) */
+ (i.e., have two or more consecutive newlines been read?) */
if (++newlines > 0)
{
@@ -422,7 +423,7 @@ cat (
which means that the buffer is empty or that a proper newline
has been found. */
- /* If quoting, i.e. at least one of -v, -e, or -t specified,
+ /* If quoting, i.e., at least one of -v, -e, or -t specified,
scan for chars that need conversion. */
if (show_nonprinting)
{
@@ -527,8 +528,8 @@ main (int argc, char **argv)
/* I-node number of the output. */
ino_t out_ino;
- /* True if the output file should not be the same as any input file. */
- bool check_redirection = true;
+ /* True if the output is a regular file. */
+ bool out_isreg;
/* Nonzero if we have ever read standard input. */
bool have_read_stdin = false;
@@ -637,25 +638,9 @@ main (int argc, char **argv)
error (EXIT_FAILURE, errno, _("standard output"));
outsize = io_blksize (stat_buf);
- /* Input file can be output file for non-regular files.
- fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
- on others, so the checking should not be done for those types,
- and to allow things like cat < /dev/tty > /dev/tty, checking
- is not done for device files either. */
-
- if (S_ISREG (stat_buf.st_mode))
- {
- out_dev = stat_buf.st_dev;
- out_ino = stat_buf.st_ino;
- }
- else
- {
- check_redirection = false;
-#ifdef lint /* Suppress 'used before initialized' warning. */
- out_dev = 0;
- out_ino = 0;
-#endif
- }
+ out_dev = stat_buf.st_dev;
+ out_ino = stat_buf.st_ino;
+ out_isreg = S_ISREG (stat_buf.st_mode) != 0;
if (! (number || show_ends || squeeze_blank))
{
@@ -704,14 +689,13 @@ main (int argc, char **argv)
fdadvise (input_desc, 0, 0, FADVISE_SEQUENTIAL);
- /* Compare the device and i-node numbers of this input file with
- the corresponding values of the (output file associated with)
- stdout, and skip this input file if they coincide. Input
- files cannot be redirected to themselves. */
+ /* Don't copy a nonempty regular file to itself, as that would
+ merely exhaust the output device. It's better to catch this
+ error earlier rather than later. */
- if (check_redirection
+ if (out_isreg
&& stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino
- && (input_desc != STDIN_FILENO))
+ && lseek (input_desc, 0, SEEK_CUR) < stat_buf.st_size)
{
error (0, 0, _("%s: input file is output file"), infile);
ok = false;
@@ -780,5 +764,5 @@ main (int argc, char **argv)
if (have_read_stdin && close (STDIN_FILENO) < 0)
error (EXIT_FAILURE, errno, _("closing standard input"));
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/chcon.c b/src/chcon.c
index cda06612..bdf61373 100644
--- a/src/chcon.c
+++ b/src/chcon.c
@@ -1,5 +1,5 @@
/* chcon -- change security context of files
- Copyright (C) 2005-2014 Free Software Foundation, Inc.
+ Copyright (C) 2005-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -401,7 +401,7 @@ one takes effect.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -582,5 +582,5 @@ main (int argc, char **argv)
ok = process_files (argv + optind, bit_flags | FTS_NOSTAT);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/chgrp.c b/src/chgrp.c
index c7297c81..eb1887e6 100644
--- a/src/chgrp.c
+++ b/src/chgrp.c
@@ -1,5 +1,5 @@
/* chgrp -- change group ownership of files
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -162,7 +162,7 @@ Examples:\n\
%s -hR staff /u Change the group of /u and subfiles to \"staff\".\n\
"),
program_name, program_name);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -313,5 +313,5 @@ main (int argc, char **argv)
chopt_free (&chopt);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/chmod.c b/src/chmod.c
index 756ec5a4..5c6881c4 100644
--- a/src/chmod.c
+++ b/src/chmod.c
@@ -1,5 +1,5 @@
/* chmod -- change permission modes of files
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -403,7 +403,7 @@ With --reference, change the mode of each FILE to that of RFILE.\n\
\n\
Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+'.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -566,5 +566,5 @@ main (int argc, char **argv)
ok = process_files (argv + optind,
FTS_COMFOLLOW | FTS_PHYSICAL | FTS_DEFER_STAT);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/chown-core.c b/src/chown-core.c
index cdcd53aa..e8a7d528 100644
--- a/src/chown-core.c
+++ b/src/chown-core.c
@@ -1,5 +1,5 @@
/* chown-core.c -- core functions for changing ownership.
- Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Copyright (C) 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/chown-core.h b/src/chown-core.h
index 86b33cd2..315be109 100644
--- a/src/chown-core.h
+++ b/src/chown-core.h
@@ -1,6 +1,6 @@
/* chown-core.h -- types and prototypes shared by chown and chgrp.
- Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Copyright (C) 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/chown.c b/src/chown.c
index 13a19233..ba1814b4 100644
--- a/src/chown.c
+++ b/src/chown.c
@@ -1,5 +1,5 @@
/* chown -- change user and group ownership of files
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -147,7 +147,7 @@ Examples:\n\
%s -hR root /u Change the owner of /u and subfiles to \"root\".\n\
"),
program_name, program_name, program_name);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -326,5 +326,5 @@ main (int argc, char **argv)
chopt_free (&chopt);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/chroot.c b/src/chroot.c
index fff0b533..42b45017 100644
--- a/src/chroot.c
+++ b/src/chroot.c
@@ -1,5 +1,5 @@
/* chroot -- run command or shell with special root directory
- Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Copyright (C) 1995-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -49,13 +49,15 @@ static inline bool gid_unset (gid_t gid) { return gid == (gid_t) -1; }
enum
{
GROUPS = UCHAR_MAX + 1,
- USERSPEC
+ USERSPEC,
+ SKIP_CHDIR
};
static struct option const long_opts[] =
{
{"groups", required_argument, NULL, GROUPS},
{"userspec", required_argument, NULL, USERSPEC},
+ {"skip-chdir", no_argument, NULL, SKIP_CHDIR},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -160,20 +162,17 @@ parse_additional_groups (char const *groups, GETGROUPS_T **pgids,
return ret;
}
+/* Return whether the passed path is equivalent to "/".
+ Note we don't compare against get_root_dev_ino() as "/"
+ could be bind mounted to a separate location. */
+
static bool
is_root (const char* dir)
{
- struct dev_ino root_ino;
- if (! get_root_dev_ino (&root_ino))
- error (EXIT_CANCELED, errno, _("failed to get attributes of %s"),
- quote ("/"));
-
- struct stat arg_st;
- if (stat (dir, &arg_st) == -1)
- error (EXIT_CANCELED, errno, _("failed to get attributes of %s"),
- quote (dir));
-
- return SAME_INODE (root_ino, arg_st);
+ char *resolved = canonicalize_file_name (dir);
+ bool is_res_root = resolved && STREQ ("/", resolved);
+ free (resolved);
+ return is_res_root;
}
void
@@ -194,9 +193,14 @@ Run COMMAND with root directory set to NEWROOT.\n\
"), stdout);
fputs (_("\
- --userspec=USER:GROUP specify user and group (ID or name) to use\n\
--groups=G_LIST specify supplementary groups as g1,g2,..,gN\n\
"), stdout);
+ fputs (_("\
+ --userspec=USER:GROUP specify user and group (ID or name) to use\n\
+"), stdout);
+ printf (_("\
+ --skip-chdir do not change working directory to %s\n\
+"), quote ("/"));
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -204,7 +208,7 @@ Run COMMAND with root directory set to NEWROOT.\n\
\n\
If no command is given, run '${SHELL} -i' (default: '/bin/sh -i').\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -218,6 +222,7 @@ main (int argc, char **argv)
char *userspec = NULL;
char const *username = NULL;
char const *groups = NULL;
+ bool skip_chdir = false;
/* Parsed user and group IDs. */
uid_t uid = -1;
@@ -254,6 +259,10 @@ main (int argc, char **argv)
groups = optarg;
break;
+ case SKIP_CHDIR:
+ skip_chdir = true;
+ break;
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -269,9 +278,17 @@ main (int argc, char **argv)
usage (EXIT_CANCELED);
}
- /* Only do chroot specific actions if actually changing root.
- The main difference here is that we don't change working dir. */
- if (! is_root (argv[optind]))
+ char const *newroot = argv[optind];
+ bool is_oldroot = is_root (newroot);
+
+ if (! is_oldroot && skip_chdir)
+ {
+ error (0, 0, _("option --skip-chdir only permitted if NEWROOT is old %s"),
+ quote ("/"));
+ usage (EXIT_CANCELED);
+ }
+
+ if (! is_oldroot)
{
/* We have to look up users and groups twice.
- First, outside the chroot to load potentially necessary passwd/group
@@ -306,14 +323,14 @@ main (int argc, char **argv)
n_gids = ngroups;
}
#endif
+ }
- if (chroot (argv[optind]) != 0)
- error (EXIT_CANCELED, errno, _("cannot change root directory to %s"),
- argv[optind]);
+ if (chroot (newroot) != 0)
+ error (EXIT_CANCELED, errno, _("cannot change root directory to %s"),
+ quote (newroot));
- if (chdir ("/"))
- error (EXIT_CANCELED, errno, _("cannot chdir to root directory"));
- }
+ if (! skip_chdir && chdir ("/"))
+ error (EXIT_CANCELED, errno, _("cannot chdir to root directory"));
if (argc == optind + 1)
{
@@ -366,7 +383,7 @@ main (int argc, char **argv)
if (parse_additional_groups (groups, &in_gids, &n_gids, !n_gids) != 0)
{
if (! n_gids)
- exit (EXIT_CANCELED);
+ return EXIT_CANCELED;
/* else look-up outside the chroot worked, then go with those. */
}
else
@@ -392,8 +409,7 @@ main (int argc, char **argv)
#endif
if ((uid_set (uid) || groups) && setgroups (n_gids, gids) != 0)
- error (EXIT_CANCELED, errno, _("failed to %s supplemental groups"),
- gids ? "set" : "clear");
+ error (EXIT_CANCELED, errno, _("failed to set supplemental groups"));
free (in_gids);
free (out_gids);
@@ -407,9 +423,7 @@ main (int argc, char **argv)
/* Execute the given command. */
execvp (argv[0], argv);
- {
- int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
- error (0, errno, _("failed to run command %s"), quote (argv[0]));
- exit (exit_status);
- }
+ int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
+ error (0, errno, _("failed to run command %s"), quote (argv[0]));
+ return exit_status;
}
diff --git a/src/cksum.c b/src/cksum.c
index 8db39a48..458827b8 100644
--- a/src/cksum.c
+++ b/src/cksum.c
@@ -1,5 +1,5 @@
/* cksum -- calculate and print POSIX checksums and sizes of files
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -102,7 +102,7 @@ main (void)
crc_remainder (i * 5 + 5));
}
printf ("\n};\n");
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
#else /* !CRCTAB */
@@ -271,7 +271,7 @@ Print CRC checksum and byte counts of each FILE.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -312,7 +312,7 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, "-");
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
#endif /* !CRCTAB */
diff --git a/src/comm.c b/src/comm.c
index 5a3eec68..ea7a2841 100644
--- a/src/comm.c
+++ b/src/comm.c
@@ -1,5 +1,5 @@
/* comm -- compare two sorted files line by line.
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -109,6 +109,10 @@ Compare sorted files FILE1 and FILE2 line by line.\n\
"), stdout);
fputs (_("\
\n\
+When FILE1 or FILE2 (not both) is -, read standard input.\n\
+"), stdout);
+ fputs (_("\
+\n\
With no options, produce three-column output. Column one contains\n\
lines unique to FILE1, column two contains lines unique to FILE2,\n\
and column three contains lines common to both files.\n\
@@ -141,7 +145,7 @@ Examples:\n\
%s -3 file1 file2 Print lines in file1 not in file2, and vice versa.\n\
"),
program_name, program_name);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -443,7 +447,7 @@ main (int argc, char **argv)
compare_files (argv + optind);
if (issued_disorder_warning[0] || issued_disorder_warning[1])
- exit (EXIT_FAILURE);
+ return EXIT_FAILURE;
else
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/copy.c b/src/copy.c
index 26d5bdd2..5fe69ea3 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1,5 +1,5 @@
/* copy.c -- core functions for copying files and directories
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -70,6 +70,10 @@
# include "verror.h"
#endif
+#if HAVE_LINUX_FALLOC_H
+# include <linux/falloc.h>
+#endif
+
#ifndef HAVE_FCHOWN
# define HAVE_FCHOWN false
# define fchown(fd, uid, gid) (-1)
@@ -100,7 +104,7 @@ rpl_mkfifo (char const *file, mode_t mode)
/* LINK_FOLLOWS_SYMLINKS is tri-state; if it is -1, we don't know
how link() behaves, so assume we can't hardlink symlinks in that case. */
-#if defined HAVE_LINKAT || ! LINK_FOLLOWS_SYMLINKS
+#if (defined HAVE_LINKAT && ! LINKAT_SYMLINK_NOTSUP) || ! LINK_FOLLOWS_SYMLINKS
# define CAN_HARDLINK_SYMLINKS 1
#else
# define CAN_HARDLINK_SYMLINKS 0
@@ -145,6 +149,53 @@ utimens_symlink (char const *file, struct timespec const *timespec)
return err;
}
+/* Attempt to punch a hole to avoid any permanent
+ speculative preallocation on file systems such as XFS.
+ Return values as per fallocate(2) except ENOSYS etc. are ignored. */
+
+static int
+punch_hole (int fd, off_t offset, off_t length)
+{
+ int ret = 0;
+#if HAVE_FALLOCATE
+# if defined FALLOC_FL_PUNCH_HOLE && defined FALLOC_FL_KEEP_SIZE
+ ret = fallocate (fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+ offset, length);
+ if (ret < 0 && (is_ENOTSUP (errno) || errno == ENOSYS))
+ ret = 0;
+# endif
+#endif
+ return ret;
+}
+
+/* Create a hole at the end of a file,
+ avoiding preallocation if requested. */
+
+static bool
+create_hole (int fd, char const *name, bool punch_holes, off_t size)
+{
+ off_t file_end = lseek (fd, size, SEEK_CUR);
+
+ if (file_end < 0)
+ {
+ error (0, errno, _("cannot lseek %s"), quote (name));
+ return false;
+ }
+
+ /* Some file systems (like XFS) preallocate when write extending a file.
+ I.e., a previous write() may have preallocated extra space
+ that the seek above will not discard. A subsequent write() could
+ then make this allocation permanent. */
+ if (punch_holes && punch_hole (fd, file_end - size, size) < 0)
+ {
+ error (0, errno, _("error deallocating %s"), quote (name));
+ return false;
+ }
+
+ return true;
+}
+
+
/* Copy the regular file open on SRC_FD/SRC_NAME to DST_FD/DST_NAME,
honoring the MAKE_HOLES setting and using the BUF_SIZE-byte buffer
BUF for temporary storage. Copy no more than MAX_N_READ bytes.
@@ -158,18 +209,18 @@ utimens_symlink (char const *file, struct timespec const *timespec)
bytes read. */
static bool
sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
- bool make_holes,
+ size_t hole_size, bool punch_holes,
char const *src_name, char const *dst_name,
uintmax_t max_n_read, off_t *total_n_read,
bool *last_write_made_hole)
{
*last_write_made_hole = false;
*total_n_read = 0;
+ bool make_hole = false;
+ off_t psize = 0;
while (max_n_read)
{
- bool make_hole = false;
-
ssize_t n_read = read (src_fd, buf, MIN (max_n_read, buf_size));
if (n_read < 0)
{
@@ -183,50 +234,94 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
max_n_read -= n_read;
*total_n_read += n_read;
- if (make_holes)
+ /* Loop over the input buffer in chunks of hole_size. */
+ size_t csize = hole_size ? hole_size : buf_size;
+ char *cbuf = buf;
+ char *pbuf = buf;
+
+ while (n_read)
{
- /* Sentinel required by is_nul(). */
- buf[n_read] = '\1';
-#ifdef lint
- typedef uintptr_t word;
- /* Usually, buf[n_read] is not the byte just before a "word"
- (aka uintptr_t) boundary. In that case, the word-oriented
- test below (*wp++ == 0) would read some uninitialized bytes
- after the sentinel. To avoid false-positive reports about
- this condition (e.g., from a tool like valgrind), set the
- remaining bytes -- to any value. */
- memset (buf + n_read + 1, 0, sizeof (word) - 1);
-#endif
+ bool prev_hole = make_hole;
+ csize = MIN (csize, n_read);
- if ((make_hole = is_nul (buf, n_read)))
+ if (hole_size && csize)
{
- if (lseek (dest_fd, n_read, SEEK_CUR) < 0)
+ /* Setup sentinel required by is_nul(). */
+ typedef uintptr_t word;
+ word isnul_tmp;
+ memcpy (&isnul_tmp, cbuf + csize, sizeof (word));
+ memset (cbuf + csize, 1, sizeof (word));
+
+ make_hole = is_nul (cbuf, csize);
+
+ memcpy (cbuf + csize, &isnul_tmp, sizeof (word));
+ }
+
+ bool transition = (make_hole != prev_hole) && psize;
+ bool last_chunk = (n_read == csize && ! make_hole) || ! csize;
+
+ if (transition || last_chunk)
+ {
+ if (! transition)
+ psize += csize;
+
+ if (! prev_hole)
{
- error (0, errno, _("cannot lseek %s"), quote (dst_name));
- return false;
+ if (full_write (dest_fd, pbuf, psize) != psize)
+ {
+ error (0, errno, _("error writing %s"), quote (dst_name));
+ return false;
+ }
+ }
+ else
+ {
+ if (! create_hole (dest_fd, dst_name, punch_holes, psize))
+ return false;
}
- }
- }
- if (!make_hole)
- {
- size_t n = n_read;
- if (full_write (dest_fd, buf, n) != n)
+ pbuf = cbuf;
+ psize = csize;
+
+ if (last_chunk)
+ {
+ if (! csize)
+ n_read = 0; /* Finished processing buffer. */
+
+ if (transition)
+ csize = 0; /* Loop again to deal with last chunk. */
+ else
+ psize = 0; /* Reset for next read loop. */
+ }
+ }
+ else /* Coalesce writes/seeks. */
{
- error (0, errno, _("error writing %s"), quote (dst_name));
- return false;
+ if (psize <= OFF_T_MAX - csize)
+ psize += csize;
+ else
+ {
+ error (0, 0, _("overflow reading %s"), quote (src_name));
+ return false;
+ }
}
- /* It is tempting to return early here upon a short read from a
- regular file. That would save the final read syscall for each
- file. Unfortunately that doesn't work for certain files in
- /proc with linux kernels from at least 2.6.9 .. 2.6.29. */
+ n_read -= csize;
+ cbuf += csize;
}
*last_write_made_hole = make_hole;
+
+ /* It's tempting to break early here upon a short read from
+ a regular file. That would save the final read syscall
+ for each file. Unfortunately that doesn't work for
+ certain files in /proc or /sys with linux kernels. */
}
- return true;
+ /* Ensure a trailing hole is created, so that subsequent
+ calls of sparse_copy() start at the correct offset. */
+ if (make_hole && ! create_hole (dest_fd, dst_name, punch_holes, psize))
+ return false;
+ else
+ return true;
}
/* Perform the O(1) btrfs clone operation, if possible.
@@ -251,7 +346,7 @@ clone_file (int dest_fd, int src_fd)
/* Write N_BYTES zero bytes to file descriptor FD. Return true if successful.
Upon write failure, set errno and return false. */
static bool
-write_zeros (int fd, uint64_t n_bytes)
+write_zeros (int fd, off_t n_bytes)
{
static char *zeros;
static size_t nz = IO_BUFSIZE;
@@ -272,7 +367,7 @@ write_zeros (int fd, uint64_t n_bytes)
while (n_bytes)
{
- uint64_t n = MIN (nz, n_bytes);
+ size_t n = MIN (nz, n_bytes);
if ((full_write (fd, zeros, n)) != n)
return false;
n_bytes -= n;
@@ -290,13 +385,14 @@ write_zeros (int fd, uint64_t n_bytes)
return false. */
static bool
extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
- off_t src_total_size, enum Sparse_type sparse_mode,
+ size_t hole_size, off_t src_total_size,
+ enum Sparse_type sparse_mode,
char const *src_name, char const *dst_name,
bool *require_normal_copy)
{
struct extent_scan scan;
off_t last_ext_start = 0;
- uint64_t last_ext_len = 0;
+ off_t last_ext_len = 0;
/* Keep track of the output position.
We may need this at the end, for a final ftruncate. */
@@ -330,8 +426,8 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
for (i = 0; i < scan.ei_count || empty_extent; i++)
{
off_t ext_start;
- uint64_t ext_len;
- uint64_t hole_size;
+ off_t ext_len;
+ off_t ext_hole_size;
if (i < scan.ei_count)
{
@@ -345,11 +441,11 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
ext_len = 0;
}
- hole_size = ext_start - last_ext_start - last_ext_len;
+ ext_hole_size = ext_start - last_ext_start - last_ext_len;
wrote_hole_at_eof = false;
- if (hole_size)
+ if (ext_hole_size)
{
if (lseek (src_fd, ext_start, SEEK_SET) < 0)
{
@@ -362,11 +458,10 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
if ((empty_extent && sparse_mode == SPARSE_ALWAYS)
|| (!empty_extent && sparse_mode != SPARSE_NEVER))
{
- if (lseek (dest_fd, ext_start, SEEK_SET) < 0)
- {
- error (0, errno, _("cannot lseek %s"), quote (dst_name));
- goto fail;
- }
+ if (! create_hole (dest_fd, dst_name,
+ sparse_mode == SPARSE_ALWAYS,
+ ext_hole_size))
+ goto fail;
wrote_hole_at_eof = true;
}
else
@@ -374,9 +469,9 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
/* When not inducing holes and when there is a hole between
the end of the previous extent and the beginning of the
current one, write zeros to the destination file. */
- off_t nzeros = hole_size;
+ off_t nzeros = ext_hole_size;
if (empty_extent)
- nzeros = MIN (src_total_size - dest_pos, hole_size);
+ nzeros = MIN (src_total_size - dest_pos, ext_hole_size);
if (! write_zeros (dest_fd, nzeros))
{
@@ -391,7 +486,7 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
last_ext_start = ext_start;
/* Treat an unwritten but allocated extent much like a hole.
- I.E. don't read, but don't convert to a hole in the destination,
+ I.e., don't read, but don't convert to a hole in the destination,
unless SPARSE_ALWAYS. */
/* For now, do not treat FIEMAP_EXTENT_UNWRITTEN specially,
because that (in combination with no sync) would lead to data
@@ -410,8 +505,8 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
last_ext_len = ext_len;
if ( ! sparse_copy (src_fd, dest_fd, buf, buf_size,
- sparse_mode == SPARSE_ALWAYS,
- src_name, dst_name, ext_len, &n_read,
+ sparse_mode == SPARSE_ALWAYS ? hole_size: 0,
+ true, src_name, dst_name, ext_len, &n_read,
&wrote_hole_at_eof))
goto fail;
@@ -453,6 +548,13 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
return false;
}
+ if (sparse_mode == SPARSE_ALWAYS && dest_pos < src_total_size
+ && punch_hole (dest_fd, dest_pos, src_total_size - dest_pos) < 0)
+ {
+ error (0, errno, _("error deallocating %s"), quote (dst_name));
+ return false;
+ }
+
return true;
}
@@ -1105,12 +1207,13 @@ copy_reg (char const *src_name, char const *dst_name,
size_t buf_alignment = lcm (getpagesize (), sizeof (word));
size_t buf_alignment_slop = sizeof (word) + buf_alignment - 1;
size_t buf_size = io_blksize (sb);
+ size_t hole_size = ST_BLKSIZE (sb);
fdadvise (source_desc, 0, 0, FADVISE_SEQUENTIAL);
/* Deal with sparse files. */
bool make_holes = false;
- bool sparse_src = false;
+ bool sparse_src = is_probably_sparse (&src_open_sb);
if (S_ISREG (sb.st_mode))
{
@@ -1123,7 +1226,6 @@ copy_reg (char const *src_name, char const *dst_name,
blocks. If the file has fewer blocks than would normally be
needed for a file of its size, then at least one of the blocks in
the file is a hole. */
- sparse_src = is_probably_sparse (&src_open_sb);
if (x->sparse_mode == SPARSE_AUTO && sparse_src)
make_holes = true;
}
@@ -1164,9 +1266,9 @@ copy_reg (char const *src_name, char const *dst_name,
standard copy only if the initial extent scan fails. If the
'--sparse=never' option is specified, write all data but use
any extents to read more efficiently. */
- if (extent_copy (source_desc, dest_desc, buf, buf_size,
+ if (extent_copy (source_desc, dest_desc, buf, buf_size, hole_size,
src_open_sb.st_size,
- S_ISREG (sb.st_mode) ? x->sparse_mode : SPARSE_NEVER,
+ make_holes ? x->sparse_mode : SPARSE_NEVER,
src_name, dst_name, &normal_copy_required))
goto preserve_metadata;
@@ -1179,12 +1281,16 @@ copy_reg (char const *src_name, char const *dst_name,
off_t n_read;
bool wrote_hole_at_eof;
- if ( ! sparse_copy (source_desc, dest_desc, buf, buf_size,
- make_holes, src_name, dst_name,
- UINTMAX_MAX, &n_read,
- &wrote_hole_at_eof)
- || (wrote_hole_at_eof
- && ftruncate (dest_desc, n_read) < 0))
+ if (! sparse_copy (source_desc, dest_desc, buf, buf_size,
+ make_holes ? hole_size : 0,
+ x->sparse_mode == SPARSE_ALWAYS, src_name, dst_name,
+ UINTMAX_MAX, &n_read,
+ &wrote_hole_at_eof))
+ {
+ return_val = false;
+ goto close_src_and_dst_desc;
+ }
+ else if (wrote_hole_at_eof && ftruncate (dest_desc, n_read) < 0)
{
error (0, errno, _("failed to extend %s"), quote (dst_name));
return_val = false;
@@ -1300,20 +1406,12 @@ close_src_desc:
copy a regular file onto a symlink that points to it.
Try to minimize the cost of this function in the common case.
Set *RETURN_NOW if we've determined that the caller has no more
- work to do and should return successfully, right away.
-
- Set *UNLINK_SRC if we've determined that the caller wants to do
- 'rename (a, b)' where 'a' and 'b' are distinct hard links to the same
- file. In that case, the caller should try to unlink 'a' and then return
- successfully. Ideally, we wouldn't have to do that, and we'd be
- able to rely on rename to remove the source file. However, POSIX
- mistakenly requires that such a rename call do *nothing* and return
- successfully. */
+ work to do and should return successfully, right away. */
static bool
same_file_ok (char const *src_name, struct stat const *src_sb,
char const *dst_name, struct stat const *dst_sb,
- const struct cp_options *x, bool *return_now, bool *unlink_src)
+ const struct cp_options *x, bool *return_now)
{
const struct stat *src_sb_link;
const struct stat *dst_sb_link;
@@ -1324,7 +1422,6 @@ same_file_ok (char const *src_name, struct stat const *src_sb,
bool same = SAME_INODE (*src_sb, *dst_sb);
*return_now = false;
- *unlink_src = false;
/* FIXME: this should (at the very least) be moved into the following
if-block. More likely, it should be removed, because it inhibits
@@ -1356,14 +1453,11 @@ same_file_ok (char const *src_name, struct stat const *src_sb,
/* Here we have two symlinks that are hard-linked together,
and we're not making backups. In this unusual case, simply
returning true would lead to mv calling "rename(A,B)",
- which would do nothing and return 0. I.e., A would
- not be removed. Hence, the solution is to tell the
- caller that all it must do is unlink A and return. */
+ which would do nothing and return 0. */
if (same_link)
{
- *unlink_src = true;
*return_now = true;
- return true;
+ return ! x->move_mode;
}
}
@@ -1431,6 +1525,7 @@ same_file_ok (char const *src_name, struct stat const *src_sb,
return true;
}
+ /* FIXME: What about case insensitive file systems ? */
return ! same_name (src_name, dst_name);
}
@@ -1451,27 +1546,21 @@ same_file_ok (char const *src_name, struct stat const *src_sb,
return true;
#endif
- /* They may refer to the same file if we're in move mode and the
- target is a symlink. That is ok, since we remove any existing
- destination file before opening it -- via 'rename' if they're on
- the same file system, via 'unlink (DST_NAME)' otherwise.
- It's also ok if they're distinct hard links to the same file. */
if (x->move_mode || x->unlink_dest_before_opening)
{
+ /* They may refer to the same file if we're in move mode and the
+ target is a symlink. That is ok, since we remove any existing
+ destination file before opening it -- via 'rename' if they're on
+ the same file system, via 'unlink (DST_NAME)' otherwise. */
if (S_ISLNK (dst_sb_link->st_mode))
return true;
+ /* It's not ok if they're distinct hard links to the same file as
+ this causes a race condition and we may lose data in this case. */
if (same_link
&& 1 < dst_sb_link->st_nlink
&& ! same_name (src_name, dst_name))
- {
- if (x->move_mode)
- {
- *unlink_src = true;
- *return_now = true;
- }
- return true;
- }
+ return ! x->move_mode;
}
/* If neither is a symlink, then it's ok as long as they aren't
@@ -1832,11 +1921,10 @@ copy_internal (char const *src_name, char const *dst_name,
{ /* Here, we know that dst_name exists, at least to the point
that it is stat'able or lstat'able. */
bool return_now;
- bool unlink_src;
have_dst_lstat = !use_stat;
if (! same_file_ok (src_name, &src_sb, dst_name, &dst_sb,
- x, &return_now, &unlink_src))
+ x, &return_now))
{
error (0, 0, _("%s and %s are the same file"),
quote_n (0, src_name), quote_n (1, dst_name));
@@ -1895,22 +1983,14 @@ copy_internal (char const *src_name, char const *dst_name,
cp and mv treat -i and -f differently. */
if (x->move_mode)
{
- if (abandon_move (x, dst_name, &dst_sb)
- || (unlink_src && unlink (src_name) == 0))
+ if (abandon_move (x, dst_name, &dst_sb))
{
/* Pretend the rename succeeded, so the caller (mv)
doesn't end up removing the source file. */
if (rename_succeeded)
*rename_succeeded = true;
- if (unlink_src && x->verbose)
- printf (_("removed %s\n"), quote (src_name));
return true;
}
- if (unlink_src)
- {
- error (0, errno, _("cannot remove %s"), quote (src_name));
- return false;
- }
}
else
{
@@ -2187,7 +2267,20 @@ copy_internal (char const *src_name, char const *dst_name,
*copy_into_self = true;
goto un_backup;
}
- else if (x->dereference == DEREF_ALWAYS)
+ else if (same_name (dst_name, earlier_file))
+ {
+ error (0, 0, _("warning: source directory %s "
+ "specified more than once"),
+ quote (top_level_src_name));
+ /* We only do backups in move mode and for non dirs,
+ and in move mode this won't be the issue as the source will
+ be missing for subsequent attempts.
+ There we just warn and return here. */
+ return true;
+ }
+ else if (x->dereference == DEREF_ALWAYS
+ || (command_line_arg
+ && x->dereference == DEREF_COMMAND_LINE_ARGUMENTS))
{
/* This happens when e.g., encountering a directory for the
second or subsequent time via symlinks when cp is invoked
diff --git a/src/copy.h b/src/copy.h
index bf194d91..bff5ff83 100644
--- a/src/copy.h
+++ b/src/copy.h
@@ -1,5 +1,5 @@
/* core functions for copying files and directories
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -254,7 +254,7 @@ struct cp_options
that was specified on the command line. Use it to avoid clobbering
source files in commands like this:
rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c
- For now, it protects only regular files when copying (i.e. not renaming).
+ For now, it protects only regular files when copying (i.e., not renaming).
When renaming, it protects all non-directories.
Use dest_info_init to initialize it, or set it to NULL to disable
this feature. */
diff --git a/src/coreutils-arch.c b/src/coreutils-arch.c
index 899cc937..fa35f261 100644
--- a/src/coreutils-arch.c
+++ b/src/coreutils-arch.c
@@ -1,5 +1,5 @@
/* arch -- wrapper to uname with the right uname_mode.
- Copyright (C) 2014 Free Software Foundation, Inc.
+ Copyright (C) 2014-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,11 +22,12 @@
#include "uname.h"
/* Ensure that the main for uname is declared even if the tool is not being
built in this single-binary. */
-int _single_binary_main_uname (int argc, char** argv) ATTRIBUTE_NORETURN;
-int _single_binary_main_arch (int argc, char** argv) ATTRIBUTE_NORETURN;
+int single_binary_main_uname (int argc, char **argv);
+int single_binary_main_arch (int argc, char **argv);
-int _single_binary_main_arch (int argc, char** argv)
+int
+single_binary_main_arch (int argc, char **argv)
{
uname_mode = UNAME_ARCH;
- _single_binary_main_uname (argc, argv);
+ return single_binary_main_uname (argc, argv);
}
diff --git a/src/coreutils-dir.c b/src/coreutils-dir.c
index 4b488f41..a90aebf8 100644
--- a/src/coreutils-dir.c
+++ b/src/coreutils-dir.c
@@ -1,5 +1,5 @@
/* dir -- wrapper to ls with the right ls_mode.
- Copyright (C) 2014 Free Software Foundation, Inc.
+ Copyright (C) 2014-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,11 +22,12 @@
#include "ls.h"
/* Ensure that the main for ls is declared even if the tool is not being built
in this single-binary. */
-int _single_binary_main_ls (int argc, char** argv) ATTRIBUTE_NORETURN;
-int _single_binary_main_dir (int argc, char** argv) ATTRIBUTE_NORETURN;
+int single_binary_main_ls (int argc, char **argv);
+int single_binary_main_dir (int argc, char **argv);
-int _single_binary_main_dir (int argc, char** argv)
+int
+single_binary_main_dir (int argc, char **argv)
{
ls_mode = LS_MULTI_COL;
- _single_binary_main_ls (argc, argv);
+ return single_binary_main_ls (argc, argv);
}
diff --git a/src/coreutils-vdir.c b/src/coreutils-vdir.c
index 036367f6..393447a7 100644
--- a/src/coreutils-vdir.c
+++ b/src/coreutils-vdir.c
@@ -1,5 +1,5 @@
/* vdir -- wrapper to ls with the right ls_mode.
- Copyright (C) 2014 Free Software Foundation, Inc.
+ Copyright (C) 2014-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,11 +22,12 @@
#include "ls.h"
/* Ensure that the main for ls is declared even if the tool is not being built
in this single-binary. */
-int _single_binary_main_ls (int argc, char** argv) ATTRIBUTE_NORETURN;
-int _single_binary_main_vdir (int argc, char** argv) ATTRIBUTE_NORETURN;
+int single_binary_main_ls (int argc, char **argv);
+int single_binary_main_vdir (int argc, char **argv);
-int _single_binary_main_vdir (int argc, char** argv)
+int
+single_binary_main_vdir (int argc, char** argv)
{
ls_mode = LS_LONG_FORMAT;
- _single_binary_main_ls (argc, argv);
+ return single_binary_main_ls (argc, argv);
}
diff --git a/src/coreutils.c b/src/coreutils.c
index c459b1d6..7f868347 100644
--- a/src/coreutils.c
+++ b/src/coreutils.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Free Software Foundation, Inc.
+/* Copyright (C) 2014-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@
needs to match the one passed as CFLAGS on single-binary.mk (generated
by gen-single-binary.sh). */
# define SINGLE_BINARY_PROGRAM(prog_name_str, main_name) \
- int _single_binary_main_##main_name (int, char**) ATTRIBUTE_NORETURN;
+ int single_binary_main_##main_name (int, char **);
# include "coreutils.h"
# undef SINGLE_BINARY_PROGRAM
#endif
@@ -46,9 +46,6 @@
#define AUTHORS \
proper_name ("Alex Deymo")
-void
-launch_program (const char *prog_name, int prog_argc, char **prog_argv);
-
static struct option const long_options[] =
{
{GETOPT_HELP_OPTION_DECL},
@@ -73,29 +70,31 @@ Execute the PROGRAM_NAME built-in program with the given PARAMETERS.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- printf ("\n\
-Built-in programs:\n"
#ifdef SINGLE_BINARY
-/* XXX: Ideally we#d like to present "install" here, not "ginstall". */
+/* XXX: Ideally we'd like to present "install" here, not "ginstall". */
+ char const *prog_name_list =
# define SINGLE_BINARY_PROGRAM(prog_name_str, main_name) " " prog_name_str
# include "coreutils.h"
# undef SINGLE_BINARY_PROGRAM
+ ;
+ printf ("\n\
+Built-in programs:\n\
+%s\n", prog_name_list);
#endif
- "\n");
printf (_("\
\n\
Use: '%s --coreutils-prog=PROGRAM_NAME --help' for individual program help.\n"),
program_name);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
-void
+static void
launch_program (const char *prog_name, int prog_argc, char **prog_argv)
{
- int (*prog_main)(int, char **) = NULL;
+ int (*prog_main) (int, char **) = NULL;
/* Ensure that at least one parameter was passed. */
if (!prog_argc || !prog_argv || !prog_argv[0] || !prog_name)
@@ -103,10 +102,10 @@ launch_program (const char *prog_name, int prog_argc, char **prog_argv)
#ifdef SINGLE_BINARY
if (false);
- /* Lookup the right main program. */
+ /* Look up the right main program. */
# define SINGLE_BINARY_PROGRAM(prog_name_str, main_name) \
else if (STREQ (prog_name_str, prog_name)) \
- prog_main = _single_binary_main_##main_name;
+ prog_main = single_binary_main_##main_name;
# include "coreutils.h"
# undef SINGLE_BINARY_PROGRAM
#endif
@@ -124,7 +123,7 @@ launch_program (const char *prog_name, int prog_argc, char **prog_argv)
prctl (PR_SET_MM_ARG_START, prog_argv[0]);
#endif
- exit ((*prog_main) (prog_argc, prog_argv));
+ exit (prog_main (prog_argc, prog_argv));
}
int
diff --git a/src/cp-hash.c b/src/cp-hash.c
index 258aff76..02a8f557 100644
--- a/src/cp-hash.c
+++ b/src/cp-hash.c
@@ -1,5 +1,5 @@
/* cp-hash.c -- file copying (hash search routines)
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/cp.c b/src/cp.c
index 99cafa7f..0ffd12d8 100644
--- a/src/cp.c
+++ b/src/cp.c
@@ -1,5 +1,5 @@
/* cp.c -- file copying (main routines)
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -268,7 +268,7 @@ As a special case, cp makes a backup of SOURCE when the force and backup\n\
options are given and SOURCE and DEST are the same name for an existing,\n\
regular file.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -1191,7 +1191,7 @@ main (int argc, char **argv)
"without an SELinux-enabled kernel"));
/* FIXME: This handles new files. But what about existing files?
- I.E. if updating a tree, new files would have the specified context,
+ I.e., if updating a tree, new files would have the specified context,
but shouldn't existing files be updated for consistency like this?
if (scontext)
restorecon (dst_path, 0, true);
@@ -1214,7 +1214,9 @@ main (int argc, char **argv)
ok = do_copy (argc - optind, argv + optind,
target_directory, no_target_directory, &x);
+#ifdef lint
forget_all ();
+#endif
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/csplit.c b/src/csplit.c
index a30f09b7..d966df57 100644
--- a/src/csplit.c
+++ b/src/csplit.c
@@ -1,5 +1,5 @@
/* csplit - split a file into sections determined by context lines
- Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ Copyright (C) 1991-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,6 +33,7 @@
#include "quote.h"
#include "safe-read.h"
#include "stdio--.h"
+#include "xdectoint.h"
#include "xstrtol.h"
/* The official name of this program (e.g., no 'g' prefix). */
@@ -1332,7 +1333,6 @@ int
main (int argc, char **argv)
{
int optc;
- unsigned long int val;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -1366,10 +1366,8 @@ main (int argc, char **argv)
break;
case 'n':
- if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
- || MIN (INT_MAX, SIZE_MAX) < val)
- error (EXIT_FAILURE, 0, _("%s: invalid number"), optarg);
- digits = val;
+ digits = xdectoimax (optarg, 0, MIN (INT_MAX, SIZE_MAX), "",
+ _("invalid number"), 0);
break;
case 's':
@@ -1466,7 +1464,7 @@ main (int argc, char **argv)
cleanup_fatal ();
}
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
void
@@ -1484,6 +1482,10 @@ Usage: %s [OPTION]... FILE PATTERN...\n\
Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ...,\n\
and output byte counts of each piece to standard output.\n\
"), stdout);
+ fputs (_("\
+\n\
+Read standard input if FILE is -\n\
+"), stdout);
emit_mandatory_arg_note ();
@@ -1504,10 +1506,7 @@ and output byte counts of each piece to standard output.\n\
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
\n\
-Read standard input if FILE is -. Each PATTERN may be:\n\
-"), stdout);
- fputs (_("\
-\n\
+Each PATTERN may be:\n\
INTEGER copy up to but not including specified line number\n\
/REGEXP/[OFFSET] copy up to but not including a matching line\n\
%REGEXP%[OFFSET] skip to, but not including a matching line\n\
@@ -1516,7 +1515,7 @@ Read standard input if FILE is -. Each PATTERN may be:\n\
\n\
A line OFFSET is a required '+' or '-' followed by a positive integer.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
diff --git a/src/cut.c b/src/cut.c
index 312551f0..4f80ebd4 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -1,5 +1,5 @@
/* cut - remove parts of lines of files
- Copyright (C) 1997-2014 Free Software Foundation, Inc.
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
Copyright (C) 1984 David M. Ihnat
This program is free software: you can redistribute it and/or modify
@@ -177,6 +177,7 @@ Usage: %s OPTION... [FILE]...\n\
Print selected parts of lines from each FILE to standard output.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -214,10 +215,8 @@ Each range is one of:\n\
N- from N'th byte, character or field, to end of line\n\
N-M from N'th to M'th (included) byte, character or field\n\
-M from first to M'th (included) byte, character or field\n\
-\n\
-With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -425,7 +424,7 @@ set_fields (const char *fieldstr)
return field_found;
}
-/* Increment *ITEM_IDX (i.e. a field or byte index),
+/* Increment *ITEM_IDX (i.e., a field or byte index),
and if required CURRENT_RP. */
static inline void
@@ -827,5 +826,5 @@ main (int argc, char **argv)
ok = false;
}
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/date.c b/src/date.c
index ef04cb58..eaee8b27 100644
--- a/src/date.c
+++ b/src/date.c
@@ -1,5 +1,5 @@
/* date - print or set the system date and time
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -132,26 +132,32 @@ Display the current time in the given FORMAT, or set the system date.\n\
emit_mandatory_arg_note ();
fputs (_("\
- -d, --date=STRING display time described by STRING, not 'now'\n\
- -f, --file=DATEFILE like --date once for each line of DATEFILE\n\
- -I[TIMESPEC], --iso-8601[=TIMESPEC] output date/time in ISO 8601 format.\n\
- TIMESPEC='date' for date only (the default),\n\
- 'hours', 'minutes', 'seconds', or 'ns' for date\n\
- and time to the indicated precision.\n\
+ -d, --date=STRING display time described by STRING, not 'now'\n\
+ -f, --file=DATEFILE like --date; once for each line of DATEFILE\n\
"), stdout);
fputs (_("\
- -r, --reference=FILE display the last modification time of FILE\n\
- -R, --rfc-2822 output date and time in RFC 2822 format.\n\
- Example: Mon, 07 Aug 2006 12:34:56 -0600\n\
+ -I[FMT], --iso-8601[=FMT] output date/time in ISO 8601 format.\n\
+ FMT='date' for date only (the default),\n\
+ 'hours', 'minutes', 'seconds', or 'ns'\n\
+ for date and time to the indicated precision.\n\
+ Example: 2006-08-14T02:34:56-0600\n\
"), stdout);
fputs (_("\
- --rfc-3339=TIMESPEC output date and time in RFC 3339 format.\n\
- TIMESPEC='date', 'seconds', or 'ns' for\n\
- date and time to the indicated precision.\n\
- Date and time components are separated by\n\
- a single space: 2006-08-07 12:34:56-06:00\n\
- -s, --set=STRING set time described by STRING\n\
- -u, --utc, --universal print or set Coordinated Universal Time (UTC)\n\
+ -R, --rfc-2822 output date and time in RFC 2822 format.\n\
+ Example: Mon, 14 Aug 2006 02:34:56 -0600\n\
+"), stdout);
+ fputs (_("\
+ --rfc-3339=FMT output date/time in RFC 3339 format.\n\
+ FMT='date', 'seconds', or 'ns'\n\
+ for date and time to the indicated precision.\n\
+ Example: 2006-08-14 02:34:56-06:00\n\
+"), stdout);
+ fputs (_("\
+ -r, --reference=FILE display the last modification time of FILE\n\
+"), stdout);
+ fputs (_("\
+ -s, --set=STRING set time described by STRING\n\
+ -u, --utc, --universal print or set Coordinated Universal Time (UTC)\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -255,7 +261,7 @@ Show the time on the west coast of the US (use tzselect(1) to find TZ)\n\
Show the local time for 9AM next Friday on the west coast of the US\n\
$ date --date='TZ=\"America/Los_Angeles\" 09:00 next Fri'\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -540,7 +546,7 @@ main (int argc, char **argv)
ok &= show_date (format, when);
}
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* Display the date and/or time in WHEN according to the format specified
diff --git a/src/dcgen b/src/dcgen
index a994be4d..b3adc790 100755
--- a/src/dcgen
+++ b/src/dcgen
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
# dcgen -- convert dircolors.hin to dircolors.h.
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/dd.c b/src/dd.c
index 1e387f3d..e6472947 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -1,5 +1,5 @@
/* dd -- convert a file while copying it.
- Copyright (C) 1985-2014 Free Software Foundation, Inc.
+ Copyright (C) 1985-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,6 +34,7 @@
#include "long-options.h"
#include "quote.h"
#include "quotearg.h"
+#include "verror.h"
#include "xstrtol.h"
#include "xtime.h"
@@ -132,11 +133,13 @@ enum
C_SPARSE = 0200000
};
-/* Status bit masks. */
+/* Status levels. */
enum
{
- STATUS_NOXFER = 01,
- STATUS_NONE = 02
+ STATUS_NONE = 1,
+ STATUS_NOXFER = 2,
+ STATUS_DEFAULT = 3,
+ STATUS_PROGRESS = 4
};
/* The name of the input file, or NULL for the standard input. */
@@ -188,7 +191,7 @@ static int input_flags = 0;
static int output_flags = 0;
/* Status flags for what is printed to stderr. */
-static int status_flags = 0;
+static int status_level = STATUS_DEFAULT;
/* If nonzero, filter characters through the translation table. */
static bool translation_needed = false;
@@ -211,6 +214,12 @@ static uintmax_t w_bytes = 0;
/* Time that dd started. */
static xtime_t start_time;
+/* Previous time for periodic progress. */
+static xtime_t previous_time;
+
+/* Whether a '\n' is pending after writing progress. */
+static bool newline_pending;
+
/* True if input is seekable. */
static bool input_seekable;
@@ -373,8 +382,9 @@ static struct symbol_value const flags[] =
/* Status, for status="...". */
static struct symbol_value const statuses[] =
{
- {"noxfer", STATUS_NOXFER},
{"none", STATUS_NONE},
+ {"noxfer", STATUS_NOXFER},
+ {"progress", STATUS_PROGRESS},
{"", 0}
};
@@ -517,6 +527,25 @@ maybe_close_stdout (void)
_exit (EXIT_FAILURE);
}
+/* Like error() but handle any pending newline. */
+
+static void _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4))
+nl_error (int status, int errnum, const char *fmt, ...)
+{
+ if (newline_pending)
+ {
+ fputc ('\n', stderr);
+ newline_pending = false;
+ }
+
+ va_list ap;
+ va_start (ap, fmt);
+ verror (status, errnum, fmt, ap);
+ va_end (ap);
+}
+
+#define error nl_error
+
void
usage (int status)
{
@@ -546,8 +575,10 @@ Copy a file, converting and formatting according to the operands.\n\
oflag=FLAGS write as per the comma separated symbol list\n\
seek=N skip N obs-sized blocks at start of output\n\
skip=N skip N ibs-sized blocks at start of input\n\
- status=WHICH WHICH info to suppress outputting to stderr;\n\
- 'noxfer' suppresses transfer stats, 'none' suppresses all\n\
+ status=LEVEL The LEVEL of information to print to stderr;\n\
+ 'none' suppresses everything but error messages,\n\
+ 'noxfer' suppresses the final transfer statistics,\n\
+ 'progress' shows periodic transfer statistics\n\
"), stdout);
fputs (_("\
\n\
@@ -627,27 +658,19 @@ Each FLAG symbol may be:\n\
"), stdout);
{
- char const *siginfo_name = (SIGINFO == SIGUSR1 ? "USR1" : "INFO");
printf (_("\
\n\
Sending a %s signal to a running 'dd' process makes it\n\
print I/O statistics to standard error and then resume copying.\n\
\n\
- $ dd if=/dev/zero of=/dev/null& pid=$!\n\
- $ kill -%s $pid; sleep 1; kill $pid\n\
- 18335302+0 records in\n\
- 18335302+0 records out\n\
- 9387674624 bytes (9.4 GB) copied, 34.6279 seconds, 271 MB/s\n\
-\n\
Options are:\n\
\n\
-"),
- siginfo_name, siginfo_name);
+"), SIGINFO == SIGUSR1 ? "USR1" : "INFO");
}
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -673,8 +696,8 @@ alloc_ibuf (void)
char *real_buf = malloc (input_blocksize + INPUT_BLOCK_SLOP);
if (!real_buf)
error (EXIT_FAILURE, 0,
- _("memory exhausted by input buffer of size %zu bytes (%s)"),
- input_blocksize, human_size (input_blocksize));
+ _("memory exhausted by input buffer of size %"PRIuMAX" bytes (%s)"),
+ (uintmax_t) input_blocksize, human_size (input_blocksize));
real_buf += SWAB_ALIGN_OFFSET; /* allow space for swab */
@@ -695,8 +718,9 @@ alloc_obuf (void)
char *real_obuf = malloc (output_blocksize + OUTPUT_BLOCK_SLOP);
if (!real_obuf)
error (EXIT_FAILURE, 0,
- _("memory exhausted by output buffer of size %zu bytes (%s)"),
- output_blocksize, human_size (output_blocksize));
+ _("memory exhausted by output buffer of size %"PRIuMAX
+ " bytes (%s)"),
+ (uintmax_t) output_blocksize, human_size (output_blocksize));
obuf = ptr_align (real_obuf, page_size);
}
else
@@ -732,8 +756,7 @@ multiple_bits_set (int i)
/* Print transfer statistics. */
static void
-print_stats (void)
-{
+print_xfer_stats (xtime_t progress_time) {
char hbuf[LONGEST_HUMAN_READABLE + 1];
int human_opts =
(human_autoscale | human_round_to_nearest
@@ -741,23 +764,8 @@ print_stats (void)
double delta_s;
char const *bytes_per_second;
- if (status_flags & STATUS_NONE)
- return;
-
- fprintf (stderr,
- _("%"PRIuMAX"+%"PRIuMAX" records in\n"
- "%"PRIuMAX"+%"PRIuMAX" records out\n"),
- r_full, r_partial, w_full, w_partial);
-
- if (r_truncate != 0)
- fprintf (stderr,
- ngettext ("%"PRIuMAX" truncated record\n",
- "%"PRIuMAX" truncated records\n",
- select_plural (r_truncate)),
- r_truncate);
-
- if (status_flags & STATUS_NOXFER)
- return;
+ if (progress_time)
+ fputc ('\r', stderr);
/* Use integer arithmetic to compute the transfer rate,
since that makes it easy to use SI abbreviations. */
@@ -769,7 +777,8 @@ print_stats (void)
w_bytes,
human_readable (w_bytes, hbuf, human_opts, 1, 1));
- xtime_t now = gethrxtime ();
+ xtime_t now = progress_time ? progress_time : gethrxtime ();
+
if (start_time < now)
{
double XTIME_PRECISIONe0 = XTIME_PRECISION;
@@ -795,7 +804,42 @@ print_stats (void)
but that was incorrect for languages like Polish. To fix this
bug we now use SI symbols even though they're a bit more
confusing in English. */
- fprintf (stderr, _(", %g s, %s/s\n"), delta_s, bytes_per_second);
+ char const *time_fmt = _(", %g s, %s/s\n");
+ if (progress_time)
+ time_fmt = _(", %.6f s, %s/s"); /* OK with '\r' as increasing width. */
+ fprintf (stderr, time_fmt, delta_s, bytes_per_second);
+
+ newline_pending = !!progress_time;
+}
+
+static void
+print_stats (void)
+{
+ if (status_level == STATUS_NONE)
+ return;
+
+ if (newline_pending)
+ {
+ fputc ('\n', stderr);
+ newline_pending = false;
+ }
+
+ fprintf (stderr,
+ _("%"PRIuMAX"+%"PRIuMAX" records in\n"
+ "%"PRIuMAX"+%"PRIuMAX" records out\n"),
+ r_full, r_partial, w_full, w_partial);
+
+ if (r_truncate != 0)
+ fprintf (stderr,
+ ngettext ("%"PRIuMAX" truncated record\n",
+ "%"PRIuMAX" truncated records\n",
+ select_plural (r_truncate)),
+ r_truncate);
+
+ if (status_level == STATUS_NOXFER)
+ return;
+
+ print_xfer_stats (0);
}
/* An ordinary signal was received; arrange for the program to exit. */
@@ -830,11 +874,7 @@ install_signal_handlers (void)
struct sigaction act;
sigemptyset (&caught_signals);
if (catch_siginfo)
- {
- sigaction (SIGINFO, NULL, &act);
- if (act.sa_handler != SIG_IGN)
- sigaddset (&caught_signals, SIGINFO);
- }
+ sigaddset (&caught_signals, SIGINFO);
sigaction (SIGINT, NULL, &act);
if (act.sa_handler != SIG_IGN)
sigaddset (&caught_signals, SIGINT);
@@ -843,6 +883,9 @@ install_signal_handlers (void)
if (sigismember (&caught_signals, SIGINFO))
{
act.sa_handler = siginfo_handler;
+ /* Note we don't use SA_RESTART here and instead
+ handle EINTR explicitly in iftruncate() etc.
+ to avoid blocking on noncommitted read()/write() calls. */
act.sa_flags = 0;
sigaction (SIGINFO, &act, NULL);
}
@@ -856,7 +899,7 @@ install_signal_handlers (void)
#else
- if (catch_siginfo && signal (SIGINFO, SIG_IGN) != SIG_IGN)
+ if (catch_siginfo)
{
signal (SIGINFO, siginfo_handler);
siginterrupt (SIGINFO, 1);
@@ -917,12 +960,18 @@ process_signals (void)
}
}
-static void ATTRIBUTE_NORETURN
-quit (int code)
+static void
+finish_up (void)
{
cleanup ();
print_stats ();
process_signals ();
+}
+
+static void ATTRIBUTE_NORETURN
+quit (int code)
+{
+ finish_up ();
exit (code);
}
@@ -938,7 +987,7 @@ cache_round (int fd, off_t len)
if (len)
{
- off_t c_pending = *pending + len;
+ uintmax_t c_pending = *pending + len;
*pending = c_pending % page_size;
if (c_pending > *pending)
len = c_pending - *pending;
@@ -1027,6 +1076,10 @@ iread (int fd, char *buf, size_t size)
}
while (nread < 0 && errno == EINTR);
+ /* Short read may be due to received signal. */
+ if (0 < nread && nread < size)
+ process_signals ();
+
if (0 < nread && warn_partial_read)
{
static ssize_t prev_nread;
@@ -1034,7 +1087,7 @@ iread (int fd, char *buf, size_t size)
if (0 < prev_nread && prev_nread < size)
{
uintmax_t prev = prev_nread;
- if (!(status_flags & STATUS_NONE))
+ if (status_level != STATUS_NONE)
error (0, 0, ngettext (("warning: partial read (%"PRIuMAX" byte); "
"suggest iflag=fullblock"),
("warning: partial read (%"PRIuMAX" bytes); "
@@ -1085,7 +1138,7 @@ iwrite (int fd, char const *buf, size_t size)
{
int old_flags = fcntl (STDOUT_FILENO, F_GETFL);
if (fcntl (STDOUT_FILENO, F_SETFL, old_flags & ~O_DIRECT) != 0
- && !(status_flags & STATUS_NONE))
+ && status_level != STATUS_NONE)
error (0, errno, _("failed to turn off O_DIRECT: %s"),
quote (output_file));
@@ -1167,6 +1220,40 @@ write_output (void)
oc = 0;
}
+/* Restart on EINTR from fd_reopen(). */
+
+static int
+ifd_reopen (int desired_fd, char const *file, int flag, mode_t mode)
+{
+ int ret;
+
+ do
+ {
+ process_signals ();
+ ret = fd_reopen (desired_fd, file, flag, mode);
+ }
+ while (ret < 0 && errno == EINTR);
+
+ return ret;
+}
+
+/* Restart on EINTR from ftruncate(). */
+
+static int
+iftruncate (int fd, off_t length)
+{
+ int ret;
+
+ do
+ {
+ process_signals ();
+ ret = ftruncate (fd, length);
+ }
+ while (ret < 0 && errno == EINTR);
+
+ return ret;
+}
+
/* Return true if STR is of the form "PATTERN" or "PATTERNDELIM...". */
static bool _GL_ATTRIBUTE_PURE
@@ -1184,7 +1271,7 @@ operand_matches (char const *str, char const *pattern, char delim)
static int
parse_symbols (char const *str, struct symbol_value const *table,
- char const *error_msgid)
+ bool exclusive, char const *error_msgid)
{
int value = 0;
@@ -1206,7 +1293,10 @@ parse_symbols (char const *str, struct symbol_value const *table,
}
}
- value |= entry->value;
+ if (exclusive)
+ value = entry->value;
+ else
+ value |= entry->value;
if (!strcomma)
break;
str = strcomma + 1;
@@ -1217,14 +1307,15 @@ parse_symbols (char const *str, struct symbol_value const *table,
/* Return the value of STR, interpreted as a non-negative decimal integer,
optionally multiplied by various values.
- Set *INVALID if STR does not represent a number in this format. */
+ Set *INVALID to a nonzero error value if STR does not represent a
+ number in this format. */
static uintmax_t
-parse_integer (const char *str, bool *invalid)
+parse_integer (const char *str, strtol_error *invalid)
{
uintmax_t n;
char *suffix;
- enum strtol_error e = xstrtoumax (str, &suffix, 10, &n, "bcEGkKMPTwYZ0");
+ strtol_error e = xstrtoumax (str, &suffix, 10, &n, "bcEGkKMPTwYZ0");
if (e == LONGINT_INVALID_SUFFIX_CHAR && *suffix == 'x')
{
@@ -1232,7 +1323,7 @@ parse_integer (const char *str, bool *invalid)
if (multiplier != 0 && n * multiplier / multiplier != n)
{
- *invalid = true;
+ *invalid = LONGINT_OVERFLOW;
return 0;
}
@@ -1240,7 +1331,7 @@ parse_integer (const char *str, bool *invalid)
}
else if (e != LONGINT_OK)
{
- *invalid = true;
+ *invalid = e;
return 0;
}
@@ -1281,40 +1372,46 @@ scanargs (int argc, char *const *argv)
else if (operand_is (name, "of"))
output_file = val;
else if (operand_is (name, "conv"))
- conversions_mask |= parse_symbols (val, conversions,
+ conversions_mask |= parse_symbols (val, conversions, false,
N_("invalid conversion"));
else if (operand_is (name, "iflag"))
- input_flags |= parse_symbols (val, flags,
+ input_flags |= parse_symbols (val, flags, false,
N_("invalid input flag"));
else if (operand_is (name, "oflag"))
- output_flags |= parse_symbols (val, flags,
+ output_flags |= parse_symbols (val, flags, false,
N_("invalid output flag"));
else if (operand_is (name, "status"))
- status_flags |= parse_symbols (val, statuses,
- N_("invalid status flag"));
+ status_level = parse_symbols (val, statuses, true,
+ N_("invalid status level"));
else
{
- bool invalid = false;
+ strtol_error invalid = LONGINT_OK;
uintmax_t n = parse_integer (val, &invalid);
+ uintmax_t n_min = 0;
+ uintmax_t n_max = UINTMAX_MAX;
if (operand_is (name, "ibs"))
{
- invalid |= ! (0 < n && n <= MAX_BLOCKSIZE (INPUT_BLOCK_SLOP));
+ n_min = 1;
+ n_max = MAX_BLOCKSIZE (INPUT_BLOCK_SLOP);
input_blocksize = n;
}
else if (operand_is (name, "obs"))
{
- invalid |= ! (0 < n && n <= MAX_BLOCKSIZE (OUTPUT_BLOCK_SLOP));
+ n_min = 1;
+ n_max = MAX_BLOCKSIZE (OUTPUT_BLOCK_SLOP);
output_blocksize = n;
}
else if (operand_is (name, "bs"))
{
- invalid |= ! (0 < n && n <= MAX_BLOCKSIZE (INPUT_BLOCK_SLOP));
+ n_min = 1;
+ n_max = MAX_BLOCKSIZE (INPUT_BLOCK_SLOP);
blocksize = n;
}
else if (operand_is (name, "cbs"))
{
- invalid |= ! (0 < n && n <= SIZE_MAX);
+ n_min = 1;
+ n_max = SIZE_MAX;
conversion_blocksize = n;
}
else if (operand_is (name, "skip"))
@@ -1329,8 +1426,14 @@ scanargs (int argc, char *const *argv)
usage (EXIT_FAILURE);
}
- if (invalid)
- error (EXIT_FAILURE, 0, _("invalid number %s"), quote (val));
+ if (n < n_min)
+ invalid = LONGINT_INVALID;
+ else if (n_max < n)
+ invalid = LONGINT_OVERFLOW;
+
+ if (invalid != LONGINT_OK)
+ error (EXIT_FAILURE, invalid == LONGINT_OVERFLOW ? EOVERFLOW : 0,
+ "%s: %s", _("invalid number"), quote (val));
}
}
@@ -1578,11 +1681,11 @@ skip_via_lseek (char const *filename, int fdesc, off_t offset, int whence)
&& ioctl (fdesc, MTIOCGET, &s2) == 0
&& MT_SAME_POSITION (s1, s2))
{
- if (!(status_flags & STATUS_NONE))
+ if (status_level != STATUS_NONE)
error (0, 0, _("warning: working around lseek kernel bug for file "
"(%s)\n of mt_type=0x%0lx -- "
"see <sys/mtio.h> for the list of types"),
- filename, s2.mt_type);
+ filename, s2.mt_type + 0Lu);
errno = 0;
new_position = -1;
}
@@ -1752,7 +1855,7 @@ advance_input_after_read_error (size_t nbytes)
if (offset == input_offset)
return true;
diff = input_offset - offset;
- if (! (0 <= diff && diff <= nbytes) && !(status_flags & STATUS_NONE))
+ if (! (0 <= diff && diff <= nbytes) && status_level != STATUS_NONE)
error (0, 0, _("warning: invalid file offset after failed read"));
if (0 <= skip_via_lseek (input_file, STDIN_FILENO, diff, SEEK_CUR))
return true;
@@ -1933,7 +2036,7 @@ dd_copy (void)
The page alignment is necessary on any Linux kernel that supports
either the SGI raw I/O patch or Steven Tweedies raw I/O patch.
- It is necessary when accessing raw (i.e. character special) disk
+ It is necessary when accessing raw (i.e., character special) disk
devices on Unixware or other SVR4-derived system. */
if (skip_records != 0 || skip_bytes != 0)
@@ -1951,7 +2054,7 @@ dd_copy (void)
2. pipe has not enough data
3. partial reads */
if ((us_blocks || (!input_offset_overflow && us_bytes))
- && !(status_flags & STATUS_NONE))
+ && status_level != STATUS_NONE)
{
error (0, 0,
_("%s: cannot skip to specified offset"), quote (input_file));
@@ -1994,6 +2097,19 @@ dd_copy (void)
while (1)
{
+ if (status_level == STATUS_PROGRESS)
+ {
+ xtime_t progress_time = gethrxtime ();
+ uintmax_t delta_xtime = progress_time;
+ delta_xtime -= previous_time;
+ double XTIME_PRECISIONe0 = XTIME_PRECISION;
+ if (delta_xtime / XTIME_PRECISIONe0 > 1)
+ {
+ print_xfer_stats (progress_time);
+ previous_time = progress_time;
+ }
+ }
+
if (r_partial + r_full >= max_records + !!max_bytes)
break;
@@ -2018,7 +2134,7 @@ dd_copy (void)
if (nread < 0)
{
- if (!(conversions_mask & C_NOERROR) || !(status_flags & STATUS_NONE))
+ if (!(conversions_mask & C_NOERROR) || status_level != STATUS_NONE)
error (0, errno, _("error reading %s"), quote (input_file));
if (conversions_mask & C_NOERROR)
@@ -2164,9 +2280,9 @@ dd_copy (void)
if (S_ISREG (stdout_stat.st_mode) || S_TYPEISSHM (&stdout_stat))
{
off_t output_offset = lseek (STDOUT_FILENO, 0, SEEK_CUR);
- if (output_offset > stdout_stat.st_size)
+ if (0 <= output_offset && stdout_stat.st_size < output_offset)
{
- if (ftruncate (STDOUT_FILENO, output_offset) != 0)
+ if (iftruncate (STDOUT_FILENO, output_offset) != 0)
{
error (0, errno,
_("failed to truncate to %" PRIdMAX " bytes"
@@ -2242,7 +2358,7 @@ main (int argc, char **argv)
}
else
{
- if (fd_reopen (STDIN_FILENO, input_file, O_RDONLY | input_flags, 0) < 0)
+ if (ifd_reopen (STDIN_FILENO, input_file, O_RDONLY | input_flags, 0) < 0)
error (EXIT_FAILURE, errno, _("failed to open %s"), quote (input_file));
}
@@ -2269,8 +2385,8 @@ main (int argc, char **argv)
need to read to satisfy a 'seek=' request. If we can't read
the file, go ahead with write-only access; it might work. */
if ((! seek_records
- || fd_reopen (STDOUT_FILENO, output_file, O_RDWR | opts, perms) < 0)
- && (fd_reopen (STDOUT_FILENO, output_file, O_WRONLY | opts, perms)
+ || ifd_reopen (STDOUT_FILENO, output_file, O_RDWR | opts, perms) < 0)
+ && (ifd_reopen (STDOUT_FILENO, output_file, O_WRONLY | opts, perms)
< 0))
error (EXIT_FAILURE, errno, _("failed to open %s"),
quote (output_file));
@@ -2287,7 +2403,7 @@ main (int argc, char **argv)
" (%lu-byte) blocks"),
seek_records, obs);
- if (ftruncate (STDOUT_FILENO, size) != 0)
+ if (iftruncate (STDOUT_FILENO, size) != 0)
{
/* Complain only when ftruncate fails on a regular file, a
directory, or a shared memory object, as POSIX 1003.1-2004
@@ -2310,7 +2426,7 @@ main (int argc, char **argv)
}
}
- start_time = gethrxtime ();
+ start_time = previous_time = gethrxtime ();
exit_status = dd_copy ();
@@ -2340,5 +2456,6 @@ main (int argc, char **argv)
invalidate_cache (STDOUT_FILENO, 0);
}
- quit (exit_status);
+ finish_up ();
+ return exit_status;
}
diff --git a/src/df.c b/src/df.c
index 3ef5d33b..2e541b95 100644
--- a/src/df.c
+++ b/src/df.c
@@ -1,5 +1,5 @@
/* df - summarize free disk space
- Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ Copyright (C) 1991-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -605,7 +605,7 @@ excluded_fstype (const char *fstype)
/* Filter mount list by skipping duplicate entries.
In the case of duplicates - based on the device number - the mount entry
- with a '/' in its me_devname (i.e. not pseudo name like tmpfs) wins.
+ with a '/' in its me_devname (i.e., not pseudo name like tmpfs) wins.
If both have a real devname (e.g. bind mounts), then that with the shorter
me_mountdir wins. With DEVICES_ONLY == true (set with df -a), only update
the global device_list, rather than filtering the global mount_list. */
@@ -622,13 +622,14 @@ filter_mount_list (bool devices_only)
struct devlist *devlist;
struct mount_entry *discard_me = NULL;
- /* TODO: On Linux we might avoid this stat() and another in get_dev()
- by using the device IDs available from /proc/self/mountinfo.
- read_file_system_list() could populate me_dev from those
- for efficiency and accuracy. */
- if (-1 == stat (me->me_mountdir, &buf))
+ /* Avoid stating remote file systems as that may hang.
+ On Linux we probably have me_dev populated from /proc/self/mountinfo,
+ however we still stat() in case another device was mounted later. */
+ if ((me->me_remote && show_local_fs)
+ || -1 == stat (me->me_mountdir, &buf))
{
- /* Stat failed - add ME to be able to complain about it later. */
+ /* If remote, and showing just local, add ME for filtering later.
+ If stat failed; add ME to be able to complain about it later. */
buf.st_dev = me->me_dev;
}
else
@@ -640,13 +641,28 @@ filter_mount_list (bool devices_only)
if (devlist)
{
- /* ...let the shorter mountdir win. */
- if ((strchr (me->me_devname, '/')
- && ! strchr (devlist->me->me_devname, '/'))
- || (strlen (devlist->me->me_mountdir)
- > strlen (me->me_mountdir))
- /* or one overmounted on a different device. */
- || ! STREQ (devlist->me->me_devname, me->me_devname))
+ if (! print_grand_total && me->me_remote && devlist->me->me_remote
+ && ! STREQ (devlist->me->me_devname, me->me_devname))
+ {
+ /* Don't discard remote entries with different locations,
+ as these are more likely to be explicitly mounted.
+ However avoid this when producing a total to give
+ a more accurate value in that case. */
+ }
+ else if ((strchr (me->me_devname, '/')
+ /* let "real" devices with '/' in the name win. */
+ && ! strchr (devlist->me->me_devname, '/'))
+ /* let a shorter mountdir win. */
+ || (strlen (devlist->me->me_mountdir)
+ > strlen (me->me_mountdir))
+ /* let an entry overmounted on a new device win... */
+ || (! STREQ (devlist->me->me_devname, me->me_devname)
+ /* ... but only when matching an existing mnt point,
+ to avoid problematic replacement when given
+ inaccurate mount lists, seen with some chroot
+ environments for example. */
+ && STREQ (me->me_mountdir,
+ devlist->me->me_mountdir)))
{
/* Discard mount entry for existing device. */
discard_me = devlist->me;
@@ -698,17 +714,17 @@ filter_mount_list (bool devices_only)
}
/* Search a mount entry list for device id DEV.
- Return the corresponding device name if found or NULL if not. */
+ Return the corresponding mount entry if found or NULL if not. */
-static char const * _GL_ATTRIBUTE_PURE
-devname_for_dev (dev_t dev)
+static struct mount_entry const * _GL_ATTRIBUTE_PURE
+me_for_dev (dev_t dev)
{
struct devlist *dl = device_list;
while (dl)
{
if (dl->dev_num == dev)
- return dl->me->me_devname;
+ return dl->me;
dl = dl->next;
}
@@ -910,6 +926,7 @@ get_dev (char const *disk, char const *mount_point, char const* file,
return;
fstype = "-";
+ fsu.fsu_bavail_top_bit_set = false;
fsu.fsu_blocksize = fsu.fsu_blocks = fsu.fsu_bfree =
fsu.fsu_bavail = fsu.fsu_files = fsu.fsu_ffree = UINTMAX_MAX;
}
@@ -923,14 +940,18 @@ get_dev (char const *disk, char const *mount_point, char const* file,
else if (process_all && show_all_fs)
{
/* Ensure we don't output incorrect stats for over-mounted directories.
- Discard stats when the device name doesn't match. */
+ Discard stats when the device name doesn't match. Though don't
+ discard when used and current mount entries are both remote due
+ to the possibility of aliased host names or exports. */
struct stat sb;
if (stat (stat_file, &sb) == 0)
{
- char const * devname = devname_for_dev (sb.st_dev);
- if (devname && ! STREQ (devname, disk))
+ struct mount_entry const * dev_me = me_for_dev (sb.st_dev);
+ if (dev_me && ! STREQ (dev_me->me_devname, disk)
+ && (! dev_me->me_remote || ! me_remote))
{
fstype = "-";
+ fsu.fsu_bavail_top_bit_set = false;
fsu.fsu_blocksize = fsu.fsu_blocks = fsu.fsu_bfree =
fsu.fsu_bavail = fsu.fsu_files = fsu.fsu_ffree = UINTMAX_MAX;
}
@@ -1391,11 +1412,10 @@ or all file systems by default.\n\
/* TRANSLATORS: The thousands and decimal separators are best
adjusted to an appropriate default for your locale. */
fputs (_("\
- -a, --all include dummy file systems\n\
+ -a, --all include pseudo, duplicate, inaccessible file systems\n\
-B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\
'-BM' prints sizes in units of 1,048,576 bytes;\n\
see SIZE format below\n\
- --total produce a grand total\n\
-h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\
-H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\
"), stdout);
@@ -1411,6 +1431,12 @@ or all file systems by default.\n\
or print all fields if FIELD_LIST is omitted.\n\
-P, --portability use the POSIX output format\n\
--sync invoke sync before getting usage info\n\
+"), stdout);
+ fputs (_("\
+ --total elide all entries insignificant to available space,\n\
+ and produce a grand total\n\
+"), stdout);
+ fputs (_("\
-t, --type=TYPE limit listing to file systems of type TYPE\n\
-T, --print-type print file system type\n\
-x, --exclude-type=TYPE limit listing to file systems not of type TYPE\n\
@@ -1425,7 +1451,7 @@ FIELD_LIST is a comma-separated list of columns to be included. Valid\n\
field names are: 'source', 'fstype', 'itotal', 'iused', 'iavail', 'ipcent',\n\
'size', 'used', 'avail', 'pcent', 'file' and 'target' (see info page).\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -1615,7 +1641,7 @@ main (int argc, char **argv)
}
}
if (match)
- exit (EXIT_FAILURE);
+ return EXIT_FAILURE;
}
if (optind < argc)
@@ -1686,6 +1712,8 @@ main (int argc, char **argv)
for (i = optind; i < argc; ++i)
if (argv[i])
get_entry (argv[i], &stats[i - optind]);
+
+ IF_LINT (free (stats));
}
else
get_all_entries ();
@@ -1709,5 +1737,5 @@ main (int argc, char **argv)
IF_LINT (free (columns));
- exit (exit_status);
+ return exit_status;
}
diff --git a/src/dircolors.c b/src/dircolors.c
index 99605367..3a03f1f2 100644
--- a/src/dircolors.c
+++ b/src/dircolors.c
@@ -1,5 +1,5 @@
/* dircolors - output commands to set the LS_COLOR environment variable
- Copyright (C) 1996-2014 Free Software Foundation, Inc.
+ Copyright (C) 1996-2015 Free Software Foundation, Inc.
Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000 H. Peter Anvin
This program is free software: you can redistribute it and/or modify
@@ -111,7 +111,7 @@ If FILE is specified, read it to determine which colors to use for which\n\
file types and extensions. Otherwise, a precompiled database is used.\n\
For details on the format of these files, run 'dircolors --print-database'.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
@@ -442,7 +442,7 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- if (!print_database < argc)
+ if ((!print_database) < argc)
{
error (0, 0, _("extra operand %s"), quote (argv[!print_database]));
if (print_database)
@@ -503,5 +503,5 @@ main (int argc, char **argv)
}
}
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/dircolors.h b/src/dircolors.h
index 7b501079..74a4494e 100644
--- a/src/dircolors.h
+++ b/src/dircolors.h
@@ -2,7 +2,7 @@ static char const G_line[] =
{
'#',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','f','i','l','e',' ','f','o','r',' ','d','i','r','c','o','l','o','r','s',',',' ','a',' ','u','t','i','l','i','t','y',' ','t','o',' ','h','e','l','p',' ','y','o','u',' ','s','e','t',' ','t','h','e',0,
'#',' ','L','S','_','C','O','L','O','R','S',' ','e','n','v','i','r','o','n','m','e','n','t',' ','v','a','r','i','a','b','l','e',' ','u','s','e','d',' ','b','y',' ','G','N','U',' ','l','s',' ','w','i','t','h',' ','t','h','e',' ','-','-','c','o','l','o','r',' ','o','p','t','i','o','n','.',0,
- '#',' ','C','o','p','y','r','i','g','h','t',' ','(','C',')',' ','1','9','9','6','-','2','0','1','4',' ','F','r','e','e',' ','S','o','f','t','w','a','r','e',' ','F','o','u','n','d','a','t','i','o','n',',',' ','I','n','c','.',0,
+ '#',' ','C','o','p','y','r','i','g','h','t',' ','(','C',')',' ','1','9','9','6','-','2','0','1','5',' ','F','r','e','e',' ','S','o','f','t','w','a','r','e',' ','F','o','u','n','d','a','t','i','o','n',',',' ','I','n','c','.',0,
'#',' ','C','o','p','y','i','n','g',' ','a','n','d',' ','d','i','s','t','r','i','b','u','t','i','o','n',' ','o','f',' ','t','h','i','s',' ','f','i','l','e',',',' ','w','i','t','h',' ','o','r',' ','w','i','t','h','o','u','t',' ','m','o','d','i','f','i','c','a','t','i','o','n',',',0,
'#',' ','a','r','e',' ','p','e','r','m','i','t','t','e','d',' ','p','r','o','v','i','d','e','d',' ','t','h','e',' ','c','o','p','y','r','i','g','h','t',' ','n','o','t','i','c','e',' ','a','n','d',' ','t','h','i','s',' ','n','o','t','i','c','e',' ','a','r','e',' ','p','r','e','s','e','r','v','e','d','.',0,
'#',' ','T','h','e',' ','k','e','y','w','o','r','d','s',' ','C','O','L','O','R',',',' ','O','P','T','I','O','N','S',',',' ','a','n','d',' ','E','I','G','H','T','B','I','T',' ','(','h','o','n','o','r','e','d',' ','b','y',' ','t','h','e',0,
@@ -84,7 +84,8 @@ static char const G_line[] =
'D','O','O','R',' ','0','1',';','3','5',' ','#',' ','d','o','o','r',0,
'B','L','K',' ','4','0',';','3','3',';','0','1',' ','#',' ','b','l','o','c','k',' ','d','e','v','i','c','e',' ','d','r','i','v','e','r',0,
'C','H','R',' ','4','0',';','3','3',';','0','1',' ','#',' ','c','h','a','r','a','c','t','e','r',' ','d','e','v','i','c','e',' ','d','r','i','v','e','r',0,
- 'O','R','P','H','A','N',' ','4','0',';','3','1',';','0','1',' ','#',' ','s','y','m','l','i','n','k',' ','t','o',' ','n','o','n','e','x','i','s','t','e','n','t',' ','f','i','l','e',',',' ','o','r',' ','n','o','n','-','s','t','a','t','\'','a','b','l','e',' ','f','i','l','e',0,
+ 'O','R','P','H','A','N',' ','4','0',';','3','1',';','0','1',' ','#',' ','s','y','m','l','i','n','k',' ','t','o',' ','n','o','n','e','x','i','s','t','e','n','t',' ','f','i','l','e',',',' ','o','r',' ','n','o','n','-','s','t','a','t','\'','a','b','l','e',' ','f','i','l','e',' ','.','.','.',0,
+ 'M','I','S','S','I','N','G',' ','0','0',' ','#',' ','.','.','.',' ','a','n','d',' ','t','h','e',' ','f','i','l','e','s',' ','t','h','e','y',' ','p','o','i','n','t',' ','t','o',0,
'S','E','T','U','I','D',' ','3','7',';','4','1',' ','#',' ','f','i','l','e',' ','t','h','a','t',' ','i','s',' ','s','e','t','u','i','d',' ','(','u','+','s',')',0,
'S','E','T','G','I','D',' ','3','0',';','4','3',' ','#',' ','f','i','l','e',' ','t','h','a','t',' ','i','s',' ','s','e','t','g','i','d',' ','(','g','+','s',')',0,
'C','A','P','A','B','I','L','I','T','Y',' ','3','0',';','4','1',' ','#',' ','f','i','l','e',' ','w','i','t','h',' ','c','a','p','a','b','i','l','i','t','y',0,
@@ -195,8 +196,6 @@ static char const G_line[] =
'.','c','g','m',' ','0','1',';','3','5',0,
'.','e','m','f',' ','0','1',';','3','5',0,
'#',' ','h','t','t','p',':','/','/','w','i','k','i','.','x','i','p','h','.','o','r','g','/','i','n','d','e','x','.','p','h','p','/','M','I','M','E','_','T','y','p','e','s','_','a','n','d','_','F','i','l','e','_','E','x','t','e','n','s','i','o','n','s',0,
- '.','a','x','v',' ','0','1',';','3','5',0,
- '.','a','n','x',' ','0','1',';','3','5',0,
'.','o','g','v',' ','0','1',';','3','5',0,
'.','o','g','x',' ','0','1',';','3','5',0,
'#',' ','a','u','d','i','o',' ','f','o','r','m','a','t','s',0,
@@ -213,8 +212,8 @@ static char const G_line[] =
'.','r','a',' ','0','0',';','3','6',0,
'.','w','a','v',' ','0','0',';','3','6',0,
'#',' ','h','t','t','p',':','/','/','w','i','k','i','.','x','i','p','h','.','o','r','g','/','i','n','d','e','x','.','p','h','p','/','M','I','M','E','_','T','y','p','e','s','_','a','n','d','_','F','i','l','e','_','E','x','t','e','n','s','i','o','n','s',0,
- '.','a','x','a',' ','0','0',';','3','6',0,
'.','o','g','a',' ','0','0',';','3','6',0,
+ '.','o','p','u','s',' ','0','0',';','3','6',0,
'.','s','p','x',' ','0','0',';','3','6',0,
'.','x','s','p','f',' ','0','0',';','3','6',0,
};
diff --git a/src/dircolors.hin b/src/dircolors.hin
index 89ebf5a1..277711f7 100644
--- a/src/dircolors.hin
+++ b/src/dircolors.hin
@@ -1,7 +1,7 @@
# Configuration file for dircolors, a utility to help you set the
# LS_COLORS environment variable used by GNU ls with the --color option.
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
# Copying and distribution of this file, with or without modification,
# are permitted provided the copyright notice and this notice are preserved.
@@ -86,7 +86,8 @@ SOCK 01;35 # socket
DOOR 01;35 # door
BLK 40;33;01 # block device driver
CHR 40;33;01 # character device driver
-ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file
+ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ...
+MISSING 00 # ... and the files they point to
SETUID 37;41 # file that is setuid (u+s)
SETGID 30;43 # file that is setgid (g+s)
CAPABILITY 30;41 # file with capability
@@ -203,8 +204,6 @@ EXEC 01;32
.emf 01;35
# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
-.axv 01;35
-.anx 01;35
.ogv 01;35
.ogx 01;35
@@ -223,7 +222,7 @@ EXEC 01;32
.wav 00;36
# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
-.axa 00;36
.oga 00;36
+.opus 00;36
.spx 00;36
.xspf 00;36
diff --git a/src/dirname.c b/src/dirname.c
index e0599a36..bdc22302 100644
--- a/src/dirname.c
+++ b/src/dirname.c
@@ -1,6 +1,6 @@
/* dirname -- strip suffix from file name
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -69,7 +69,7 @@ Examples:\n\
%s stdio.h -> \".\"\n\
"),
program_name, program_name, program_name);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -132,5 +132,5 @@ main (int argc, char **argv)
putchar (use_nuls ? '\0' :'\n');
}
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/du.c b/src/du.c
index 0966326b..86827f80 100644
--- a/src/du.c
+++ b/src/du.c
@@ -1,5 +1,5 @@
/* du -- summarize disk usage
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -283,7 +283,7 @@ Usage: %s [OPTION]... [FILE]...\n\
or: %s [OPTION]... --files0-from=F\n\
"), program_name, program_name);
fputs (_("\
-Summarize disk usage of each FILE, recursively for directories.\n\
+Summarize disk usage of the set of FILEs, recursively for directories.\n\
"), stdout);
emit_mandatory_arg_note ();
@@ -351,7 +351,7 @@ Summarize disk usage of each FILE, recursively for directories.\n\
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_blocksize_note ("DU");
emit_size_note ();
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -419,6 +419,27 @@ print_size (const struct duinfo *pdui, const char *string)
fflush (stdout);
}
+/* This function checks whether any of the directories in the cycle that
+ fts detected is a mount point. */
+
+static bool
+mount_point_in_fts_cycle (FTSENT const *ent)
+{
+ FTSENT const *cycle_ent = ent->fts_cycle;
+
+ while (ent && ent != cycle_ent)
+ {
+ if (di_set_lookup (di_mnt, ent->fts_statp->st_dev,
+ ent->fts_statp->st_ino) > 0)
+ {
+ return true;
+ }
+ ent = ent->fts_parent;
+ }
+
+ return false;
+}
+
/* This function is called once for every file system object that fts
encounters. fts does a depth-first traversal. This function knows
that and accumulates per-directory totals based on changes in
@@ -516,7 +537,7 @@ process_file (FTS *fts, FTSENT *ent)
case FTS_DC:
/* If not following symlinks and not a (bind) mount point. */
if (cycle_warning_required (fts, ent)
- && ! di_set_lookup (di_mnt, sb->st_dev, sb->st_ino))
+ && ! mount_point_in_fts_cycle (ent))
{
emit_cycle_warning (file);
return false;
@@ -947,9 +968,9 @@ main (int argc, char **argv)
{
/* Ignore "posix-" prefix, for compatibility with ls. */
static char const posix_prefix[] = "posix-";
- while (strncmp (time_style, posix_prefix, sizeof posix_prefix - 1)
- == 0)
- time_style += sizeof posix_prefix - 1;
+ static const size_t prefix_len = sizeof posix_prefix - 1;
+ while (STREQ_LEN (time_style, posix_prefix, prefix_len))
+ time_style += prefix_len;
}
}
@@ -1108,5 +1129,5 @@ main (int argc, char **argv)
if (print_grand_total)
print_size (&tot_dui, _("total"));
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/echo.c b/src/echo.c
index 93f4a820..222b12bf 100644
--- a/src/echo.c
+++ b/src/echo.c
@@ -1,5 +1,5 @@
/* echo.c, derived from code echo.c in Bash.
- Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -79,7 +79,7 @@ If -e is in effect, the following sequences are recognized:\n\
\\xHH byte with hexadecimal value HH (1 to 2 digits)\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -136,7 +136,7 @@ main (int argc, char **argv)
{
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
(char *) NULL);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
}
@@ -204,7 +204,7 @@ just_echo:
{
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
- case 'c': exit (EXIT_SUCCESS);
+ case 'c': return EXIT_SUCCESS;
case 'e': c = '\x1B'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
@@ -268,5 +268,5 @@ just_echo:
if (display_return)
putchar ('\n');
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/env.c b/src/env.c
index 2b37d986..270d08e3 100644
--- a/src/env.c
+++ b/src/env.c
@@ -1,5 +1,5 @@
/* env - run a program in a modified environment
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -69,7 +69,7 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\
\n\
A mere - implies -i. If no COMMAND, print the resulting environment.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -144,7 +144,7 @@ main (int argc, char **argv)
char *const *e = environ;
while (*e)
printf ("%s%c", *e++, opt_nul_terminate_output ? '\0' : '\n');
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
if (opt_nul_terminate_output)
@@ -155,9 +155,7 @@ main (int argc, char **argv)
execvp (argv[optind], &argv[optind]);
- {
- int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
- error (0, errno, "%s", argv[optind]);
- exit (exit_status);
- }
+ int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
+ error (0, errno, "%s", argv[optind]);
+ return exit_status;
}
diff --git a/src/expand.c b/src/expand.c
index 082b5d4e..0a40a1a8 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -1,5 +1,5 @@
/* expand - convert tabs to spaces
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -106,9 +106,9 @@ Usage: %s [OPTION]... [FILE]...\n\
program_name);
fputs (_("\
Convert tabs in each FILE to spaces, writing to standard output.\n\
-With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -120,7 +120,7 @@ With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -426,5 +426,5 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) != 0)
error (EXIT_FAILURE, errno, "-");
- exit (exit_status);
+ return exit_status;
}
diff --git a/src/expr.c b/src/expr.c
index a97663a1..b368e237 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1,5 +1,5 @@
/* expr -- evaluate expressions.
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -265,7 +265,7 @@ Pattern matches return the string matched between \\( and \\) or null; if\n\
Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION is null\n\
or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -326,7 +326,7 @@ main (int argc, char **argv)
syntax_error ();
printv (v);
- exit (null (v));
+ return null (v);
}
/* Return a VALUE for I. */
diff --git a/src/extent-scan.c b/src/extent-scan.c
index 805997a7..e0a065e7 100644
--- a/src/extent-scan.c
+++ b/src/extent-scan.c
@@ -1,5 +1,5 @@
/* extent-scan.c -- core functions for scanning extents
- Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Copyright (C) 2010-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -140,6 +140,8 @@ extent_scan_read (struct extent_scan *scan)
assert (fm_extents[i].fe_logical
<= OFF_T_MAX - fm_extents[i].fe_length);
+ verify (sizeof last_ei->ext_flags >= sizeof fm_extents->fe_flags);
+
if (si && last_ei->ext_flags
== (fm_extents[i].fe_flags & ~FIEMAP_EXTENT_LAST)
&& (last_ei->ext_logical + last_ei->ext_length
diff --git a/src/extent-scan.h b/src/extent-scan.h
index fa800343..e91ad433 100644
--- a/src/extent-scan.h
+++ b/src/extent-scan.h
@@ -1,5 +1,5 @@
/* core functions for efficient reading sparse files
- Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Copyright (C) 2010-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,10 +26,10 @@ struct extent_info
off_t ext_logical;
/* Extent length. */
- uint64_t ext_length;
+ off_t ext_length;
/* Extent flags, use it for FIEMAP only, or set it to zero. */
- uint32_t ext_flags;
+ unsigned int ext_flags;
};
/* Structure used to reserve extent scan information per file. */
@@ -42,10 +42,10 @@ struct extent_scan
off_t scan_start;
/* Flags to use for scan. */
- uint32_t fm_flags;
+ unsigned int fm_flags;
/* How many extent info returned for a scan. */
- uint32_t ei_count;
+ size_t ei_count;
/* If true, fall back to a normal copy, either set by the
failure of ioctl(2) for FIEMAP or lseek(2) with SEEK_DATA. */
diff --git a/src/extract-magic b/src/extract-magic
index 5b6f6185..1061dd55 100644
--- a/src/extract-magic
+++ b/src/extract-magic
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
# Derive #define directives from specially formatted 'case ...:' statements.
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2015 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/factor.c b/src/factor.c
index 63924d54..1d7d7c8d 100644
--- a/src/factor.c
+++ b/src/factor.c
@@ -1,5 +1,5 @@
/* factor -- print prime factors of n.
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -98,6 +98,7 @@
#include "system.h"
#include "error.h"
+#include "full-write.h"
#include "quote.h"
#include "readtokens.h"
#include "xstrtol.h"
@@ -1811,9 +1812,9 @@ isqrt2 (uintmax_t nh, uintmax_t nl)
}
/* MAGIC[N] has a bit i set iff i is a quadratic residue mod N. */
-#define MAGIC64 ((uint64_t) 0x0202021202030213ULL)
-#define MAGIC63 ((uint64_t) 0x0402483012450293ULL)
-#define MAGIC65 ((uint64_t) 0x218a019866014613ULL)
+#define MAGIC64 0x0202021202030213ULL
+#define MAGIC63 0x0402483012450293ULL
+#define MAGIC65 0x218a019866014613ULL
#define MAGIC11 0x23b
/* Return the square root if the input is a square, otherwise 0. */
@@ -2055,8 +2056,9 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
div_smallq (q, rem, S+P, Q);
P1 = S - rem; /* P1 = q*Q - P */
+ IF_LINT (assert (q > 0 && Q > 0));
+
#if STAT_SQUFOF
- assert (q > 0);
q_freq[0]++;
q_freq[MIN (q, Q_FREQ_SIZE)]++;
#endif
@@ -2322,13 +2324,100 @@ strto2uintmax (uintmax_t *hip, uintmax_t *lop, const char *s)
return err;
}
+/* Structure and routines for buffering and outputting full lines,
+ to support parallel operation efficiently. */
+static struct lbuf_
+{
+ char *buf;
+ char *end;
+} lbuf;
+
+/* 512 is chosen to give good performance,
+ and also is the max guaranteed size that
+ consumers can read atomically through pipes.
+ Also it's big enough to cater for max line length
+ even with 128 bit uintmax_t. */
+#define FACTOR_PIPE_BUF 512
+
+static void
+lbuf_alloc (void)
+{
+ if (lbuf.buf)
+ return;
+
+ /* Double to ensure enough space for
+ previous numbers + next number. */
+ lbuf.buf = xmalloc (FACTOR_PIPE_BUF * 2);
+ lbuf.end = lbuf.buf;
+}
+
+/* Write complete LBUF to standard output. */
+static void
+lbuf_flush (void)
+{
+ size_t size = lbuf.end - lbuf.buf;
+ if (full_write (STDOUT_FILENO, lbuf.buf, size) != size)
+ error (EXIT_FAILURE, errno, "%s", _("write error"));
+ lbuf.end = lbuf.buf;
+}
+
+/* Add a character C to LBUF and if it's a newline
+ and enough bytes are already buffered,
+ then write atomically to standard output. */
+static void
+lbuf_putc (char c)
+{
+ *lbuf.end++ = c;
+
+ if (c == '\n')
+ {
+ size_t buffered = lbuf.end - lbuf.buf;
+
+ if (buffered >= FACTOR_PIPE_BUF)
+ {
+ /* Write output in <= PIPE_BUF chunks
+ so consumers can read atomically. */
+ char const *tend = lbuf.end;
+
+ /* Since a umaxint_t's factors must fit in 512
+ we're guaranteed to find a newline here. */
+ char *tlend = lbuf.buf + FACTOR_PIPE_BUF;
+ while (*--tlend != '\n');
+ tlend++;
+
+ lbuf.end = tlend;
+ lbuf_flush ();
+
+ /* Buffer the remainder. */
+ memcpy (lbuf.buf, tlend, tend - tlend);
+ lbuf.end = lbuf.buf + (tend - tlend);
+ }
+ }
+}
+
+/* Buffer an int to the internal LBUF. */
+static void
+lbuf_putint (uintmax_t i, size_t min_width)
+{
+ char buf[INT_BUFSIZE_BOUND (uintmax_t)];
+ char const *umaxstr = umaxtostr (i, buf);
+ size_t width = sizeof (buf) - (umaxstr - buf) - 1;
+ size_t z = width;
+
+ for (; z < min_width; z++)
+ *lbuf.end++ = '0';
+
+ memcpy (lbuf.end, umaxstr, width);
+ lbuf.end += width;
+}
+
static void
print_uintmaxes (uintmax_t t1, uintmax_t t0)
{
uintmax_t q, r;
if (t1 == 0)
- printf ("%"PRIuMAX, t0);
+ lbuf_putint (t0, 0);
else
{
/* Use very plain code here since it seems hard to write fast code
@@ -2337,7 +2426,7 @@ print_uintmaxes (uintmax_t t1, uintmax_t t0)
r = t1 % 1000000000;
udiv_qrnnd (t0, r, r, t0, 1000000000);
print_uintmaxes (q, t0);
- printf ("%09u", (int) r);
+ lbuf_putint (r, 9);
}
}
@@ -2348,24 +2437,24 @@ print_factors_single (uintmax_t t1, uintmax_t t0)
struct factors factors;
print_uintmaxes (t1, t0);
- putchar (':');
+ lbuf_putc (':');
factor (t1, t0, &factors);
for (unsigned int j = 0; j < factors.nfactors; j++)
for (unsigned int k = 0; k < factors.e[j]; k++)
{
- char buf[INT_BUFSIZE_BOUND (uintmax_t)];
- putchar (' ');
- fputs (umaxtostr (factors.p[j], buf), stdout);
+ lbuf_putc (' ');
+ print_uintmaxes (0, factors.p[j]);
}
if (factors.plarge[1])
{
- putchar (' ');
+ lbuf_putc (' ');
print_uintmaxes (factors.plarge[1], factors.plarge[0]);
}
- putchar ('\n');
+
+ lbuf_putc ('\n');
}
/* Emit the factors of the indicated number. If we have the option of using
@@ -2421,6 +2510,7 @@ print_factors (const char *input)
mp_factor_clear (&factors);
mpz_clear (t);
putchar ('\n');
+ fflush (stdout);
return true;
#else
error (0, 0, _("%s is too large"), quote (input));
@@ -2447,7 +2537,7 @@ are specified on the command line, read them from standard input.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -2482,7 +2572,9 @@ main (int argc, char **argv)
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
+ lbuf_alloc ();
atexit (close_stdout);
+ atexit (lbuf_flush);
alg = ALG_POLLARD_RHO; /* Default to Pollard rho */
@@ -2543,5 +2635,5 @@ main (int argc, char **argv)
}
#endif
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/fiemap.h b/src/fiemap.h
index 15ddff9a..88a9fa61 100644
--- a/src/fiemap.h
+++ b/src/fiemap.h
@@ -95,7 +95,7 @@ struct fiemap
/* Multiple files in block. Set EXTENT_NOT_ALIGNED. */
# define FIEMAP_EXTENT_DATA_TAIL 0x00000400
-/* Space allocated, but not data (i.e. zero). */
+/* Space allocated, but not data (i.e., zero). */
# define FIEMAP_EXTENT_UNWRITTEN 0x00000800
/* File does not natively support extents. Result merged for efficiency. */
diff --git a/src/find-mount-point.c b/src/find-mount-point.c
index 869d81c6..59a60e27 100644
--- a/src/find-mount-point.c
+++ b/src/find-mount-point.c
@@ -1,5 +1,5 @@
/* find-mount-point.c -- find the root mount point for a file.
- Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Copyright (C) 2010-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/find-mount-point.h b/src/find-mount-point.h
index c8a66dd8..195ec902 100644
--- a/src/find-mount-point.h
+++ b/src/find-mount-point.h
@@ -1,5 +1,5 @@
/* find-mount-point.h -- find the root mount point for a file.
- Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Copyright (C) 2010-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/fmt.c b/src/fmt.c
index dbd180b4..b12c9b9e 100644
--- a/src/fmt.c
+++ b/src/fmt.c
@@ -1,5 +1,5 @@
/* GNU fmt -- simple text formatter.
- Copyright (C) 1994-2014 Free Software Foundation, Inc.
+ Copyright (C) 1994-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
#include "error.h"
#include "fadvise.h"
#include "quote.h"
-#include "xstrtol.h"
+#include "xdectoint.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "fmt"
@@ -273,6 +273,7 @@ Reformat each paragraph in the FILE(s), writing to standard output.\n\
The option -WIDTH is an abbreviated form of --width=DIGITS.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -292,11 +293,7 @@ The option -WIDTH is an abbreviated form of --width=DIGITS.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
-With no FILE, or when FILE is -, read standard input.\n"),
- stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -399,23 +396,15 @@ main (int argc, char **argv)
{
/* Limit max_width to MAXCHARS / 2; otherwise, the resulting
output can be quite ugly. */
- unsigned long int tmp;
- if (! (xstrtoul (max_width_option, NULL, 10, &tmp, "") == LONGINT_OK
- && tmp <= MAXCHARS / 2))
- error (EXIT_FAILURE, 0, _("invalid width: %s"),
- quote (max_width_option));
- max_width = tmp;
+ max_width = xdectoumax (max_width_option, 0, MAXCHARS / 2, "",
+ _("invalid width"), 0);
}
if (goal_width_option)
{
/* Limit goal_width to max_width. */
- unsigned long int tmp;
- if (! (xstrtoul (goal_width_option, NULL, 10, &tmp, "") == LONGINT_OK
- && tmp <= max_width))
- error (EXIT_FAILURE, 0, _("invalid width: %s"),
- quote (goal_width_option));
- goal_width = tmp;
+ goal_width = xdectoumax (goal_width_option, 0, max_width, "",
+ _("invalid width"), 0);
if (max_width_option == NULL)
max_width = goal_width + 10;
}
@@ -456,7 +445,7 @@ main (int argc, char **argv)
}
}
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* Trim space from the front and back of the string P, yielding the prefix,
diff --git a/src/fold.c b/src/fold.c
index 444dc8b4..0955c09d 100644
--- a/src/fold.c
+++ b/src/fold.c
@@ -1,5 +1,5 @@
/* fold -- wrap each input line to fit in specified width.
- Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ Copyright (C) 1991-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,8 +25,7 @@
#include "system.h"
#include "error.h"
#include "fadvise.h"
-#include "quote.h"
-#include "xstrtol.h"
+#include "xdectoint.h"
#define TAB_WIDTH 8
@@ -68,10 +67,10 @@ Usage: %s [OPTION]... [FILE]...\n\
"),
program_name);
fputs (_("\
-Wrap input lines in each FILE (standard input by default), writing to\n\
-standard output.\n\
+Wrap input lines in each FILE, writing to standard output.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -81,7 +80,7 @@ standard output.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -280,14 +279,8 @@ main (int argc, char **argv)
}
/* Fall through. */
case 'w': /* Line width. */
- {
- unsigned long int tmp_ulong;
- if (! (xstrtoul (optarg, NULL, 10, &tmp_ulong, "") == LONGINT_OK
- && 0 < tmp_ulong && tmp_ulong < SIZE_MAX - TAB_WIDTH))
- error (EXIT_FAILURE, 0,
- _("invalid number of columns: %s"), quote (optarg));
- width = tmp_ulong;
- }
+ width = xdectoumax (optarg, 1, SIZE_MAX - TAB_WIDTH - 1, "",
+ _("invalid number of columns"), 0);
break;
case_GETOPT_HELP_CHAR;
@@ -311,5 +304,5 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, "-");
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/fs-is-local.h b/src/fs-is-local.h
index 2a7deee0..215f0b8f 100644
--- a/src/fs-is-local.h
+++ b/src/fs-is-local.h
@@ -50,6 +50,7 @@ is_local_fs_type (unsigned long int magic)
case S_MAGIC_HPFS: return 1;
case S_MAGIC_HUGETLBFS: return 1;
case S_MAGIC_MTD_INODE_FS: return 1;
+ case S_MAGIC_IBRIX: return 0;
case S_MAGIC_INOTIFYFS: return 1;
case S_MAGIC_ISOFS: return 1;
case S_MAGIC_ISOFS_R_WIN: return 1;
diff --git a/src/fs.h b/src/fs.h
index 4ed73c60..e1034f4e 100644
--- a/src/fs.h
+++ b/src/fs.h
@@ -47,6 +47,7 @@
# define S_MAGIC_HPFS 0xF995E849
# define S_MAGIC_HUGETLBFS 0x958458F6
# define S_MAGIC_MTD_INODE_FS 0x11307854
+# define S_MAGIC_IBRIX 0x013111A8
# define S_MAGIC_INOTIFYFS 0x2BAD1DEA
# define S_MAGIC_ISOFS 0x9660
# define S_MAGIC_ISOFS_R_WIN 0x4004
diff --git a/src/getlimits.c b/src/getlimits.c
index 597efd82..d5af741c 100644
--- a/src/getlimits.c
+++ b/src/getlimits.c
@@ -1,5 +1,5 @@
/* getlimits - print various platform dependent limits.
- Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -73,7 +73,7 @@ Output platform dependent limits in a format useful for shell scripts.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -167,4 +167,6 @@ main (int argc, char **argv)
print_float (FLT);
print_float (DBL);
print_float (LDBL);
+
+ return EXIT_SUCCESS;
}
diff --git a/src/group-list.c b/src/group-list.c
index 823384f5..5d7a8f20 100644
--- a/src/group-list.c
+++ b/src/group-list.c
@@ -1,5 +1,5 @@
/* group-list.c --Print a list of group IDs or names.
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/group-list.h b/src/group-list.h
index 806f78fd..46d6f9f3 100644
--- a/src/group-list.h
+++ b/src/group-list.h
@@ -1,6 +1,6 @@
/* group-list.h -- prototypes shared by id and groups.
- Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/groups.c b/src/groups.c
index f19ff0ac..99eafb6c 100644
--- a/src/groups.c
+++ b/src/groups.c
@@ -1,5 +1,5 @@
/* groups -- print the groups a user is in
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -58,7 +58,7 @@ the current process (which may differ if the groups database has changed).\n"),
stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -136,5 +136,5 @@ main (int argc, char **argv)
}
}
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/head.c b/src/head.c
index 65bd52a1..410cc4f4 100644
--- a/src/head.c
+++ b/src/head.c
@@ -1,5 +1,5 @@
/* head -- output first part of file(s)
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,8 +36,9 @@
#include "quote.h"
#include "quotearg.h"
#include "safe-read.h"
+#include "stat-size.h"
#include "xfreopen.h"
-#include "xstrtol.h"
+#include "xdectoint.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "head"
@@ -109,9 +110,9 @@ Usage: %s [OPTION]... [FILE]...\n\
fputs (_("\
Print the first 10 lines of each FILE to standard output.\n\
With more than one FILE, precede each with a header giving the file name.\n\
-With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -134,7 +135,7 @@ K may have a multiplier suffix:\n\
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\
GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -206,13 +207,42 @@ copy_fd (int src_fd, uintmax_t n_bytes)
return COPY_FD_OK;
}
-/* Print all but the last N_ELIDE bytes from the input available via
- the non-seekable file descriptor FD. Return true upon success.
+/* Call lseek (FD, OFFSET, WHENCE), where file descriptor FD
+ corresponds to the file FILENAME. WHENCE must be SEEK_SET or
+ SEEK_CUR. Return the resulting offset. Give a diagnostic and
+ return -1 if lseek fails. */
+
+static off_t
+elseek (int fd, off_t offset, int whence, char const *filename)
+{
+ off_t new_offset = lseek (fd, offset, whence);
+ char buf[INT_BUFSIZE_BOUND (offset)];
+
+ if (new_offset < 0)
+ error (0, errno,
+ _(whence == SEEK_SET
+ ? N_("%s: cannot seek to offset %s")
+ : N_("%s: cannot seek to relative offset %s")),
+ quotearg_colon (filename),
+ offtostr (offset, buf));
+
+ return new_offset;
+}
+
+/* For an input file with name FILENAME and descriptor FD,
+ output all but the last N_ELIDE_0 bytes.
+ If CURRENT_POS is nonnegative, assume that the input file is
+ positioned at CURRENT_POS and that it should be repositioned to
+ just before the elided bytes before returning.
+ Return true upon success.
Give a diagnostic and return false upon error. */
static bool
-elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
+elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0,
+ off_t current_pos)
{
size_t n_elide = n_elide_0;
+ uintmax_t desired_pos = current_pos;
+ bool ok = true;
#ifndef HEAD_TAIL_PIPE_READ_BUFSIZE
# define HEAD_TAIL_PIPE_READ_BUFSIZE BUFSIZ
@@ -251,7 +281,6 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
if (n_elide <= HEAD_TAIL_PIPE_BYTECOUNT_THRESHOLD)
{
- bool ok = true;
bool first = true;
bool eof = false;
size_t n_to_read = READ_BUFSIZE + n_elide;
@@ -293,22 +322,26 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
/* Output any (but maybe just part of the) elided data from
the previous round. */
if (! first)
- xwrite_stdout (b[!i] + READ_BUFSIZE, n_elide - delta);
+ {
+ desired_pos += n_elide - delta;
+ xwrite_stdout (b[!i] + READ_BUFSIZE, n_elide - delta);
+ }
first = false;
if (n_elide < n_read)
- xwrite_stdout (b[i], n_read - n_elide);
+ {
+ desired_pos += n_read - n_elide;
+ xwrite_stdout (b[i], n_read - n_elide);
+ }
}
free (b[0]);
- return ok;
}
else
{
/* Read blocks of size READ_BUFSIZE, until we've read at least n_elide
bytes. Then, for each new buffer we read, also write an old one. */
- bool ok = true;
bool eof = false;
size_t n_read;
bool buffered_enough;
@@ -357,7 +390,10 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
buffered_enough = true;
if (buffered_enough)
- xwrite_stdout (b[i_next], n_read);
+ {
+ desired_pos += n_read;
+ xwrite_stdout (b[i_next], n_read);
+ }
}
/* Output any remainder: rem bytes from b[i] + n_read. */
@@ -366,6 +402,7 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
if (buffered_enough)
{
size_t n_bytes_left_in_b_i = READ_BUFSIZE - n_read;
+ desired_pos += rem;
if (rem < n_bytes_left_in_b_i)
{
xwrite_stdout (b[i] + n_read, rem);
@@ -392,6 +429,7 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
*/
size_t y = READ_BUFSIZE - rem;
size_t x = n_read - y;
+ desired_pos += x;
xwrite_stdout (b[i_next], x);
}
}
@@ -400,36 +438,16 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
for (i = 0; i < n_alloc; i++)
free (b[i]);
free (b);
-
- return ok;
}
-}
-/* Call lseek (FD, OFFSET, WHENCE), where file descriptor FD
- corresponds to the file FILENAME. WHENCE must be SEEK_SET or
- SEEK_CUR. Return the resulting offset. Give a diagnostic and
- return -1 if lseek fails. */
-
-static off_t
-elseek (int fd, off_t offset, int whence, char const *filename)
-{
- off_t new_offset = lseek (fd, offset, whence);
- char buf[INT_BUFSIZE_BOUND (offset)];
-
- if (new_offset < 0)
- error (0, errno,
- _(whence == SEEK_SET
- ? N_("%s: cannot seek to offset %s")
- : N_("%s: cannot seek to relative offset %s")),
- quotearg_colon (filename),
- offtostr (offset, buf));
-
- return new_offset;
+ if (0 <= current_pos && elseek (fd, desired_pos, SEEK_SET, filename) < 0)
+ ok = false;
+ return ok;
}
/* For the file FILENAME with descriptor FD, output all but the last N_ELIDE
bytes. If SIZE is nonnegative, this is a regular file positioned
- at START_POS with SIZE bytes. Return true on success.
+ at CURRENT_POS with SIZE bytes. Return true on success.
Give a diagnostic and return false upon error. */
/* NOTE: if the input file shrinks by more than N_ELIDE bytes between
@@ -437,10 +455,11 @@ elseek (int fd, off_t offset, int whence, char const *filename)
static bool
elide_tail_bytes_file (const char *filename, int fd, uintmax_t n_elide,
- off_t current_pos, off_t size)
+ struct stat const *st, off_t current_pos)
{
- if (size < 0)
- return elide_tail_bytes_pipe (filename, fd, n_elide);
+ off_t size = st->st_size;
+ if (presume_input_pipe || size <= ST_BLKSIZE (*st))
+ return elide_tail_bytes_pipe (filename, fd, n_elide, current_pos);
else
{
/* Be careful here. The current position may actually be
@@ -460,13 +479,16 @@ elide_tail_bytes_file (const char *filename, int fd, uintmax_t n_elide,
}
}
-/* Print all but the last N_ELIDE lines from the input stream
- open for reading via file descriptor FD.
+/* For an input file with name FILENAME and descriptor FD,
+ output all but the last N_ELIDE_0 bytes.
+ If CURRENT_POS is nonnegative, the input file is positioned there
+ and should be repositioned to just before the elided bytes.
Buffer the specified number of lines as a linked list of LBUFFERs,
adding them as needed. Return true if successful. */
static bool
-elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
+elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide,
+ off_t current_pos)
{
struct linebuffer
{
@@ -475,6 +497,7 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
size_t nlines;
struct linebuffer *next;
};
+ uintmax_t desired_pos = current_pos;
typedef struct linebuffer LBUFFER;
LBUFFER *first, *last, *tmp;
size_t total_lines = 0; /* Total number of newlines in all buffers. */
@@ -497,6 +520,7 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
if (! n_elide)
{
+ desired_pos += n_read;
xwrite_stdout (tmp->buffer, n_read);
continue;
}
@@ -536,6 +560,7 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
last = last->next = tmp;
if (n_elide < total_lines - first->nlines)
{
+ desired_pos += first->nbytes;
xwrite_stdout (first->buffer, first->nbytes);
tmp = first;
total_lines -= first->nlines;
@@ -565,6 +590,7 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
for (tmp = first; n_elide < total_lines - tmp->nlines; tmp = tmp->next)
{
+ desired_pos += tmp->nbytes;
xwrite_stdout (tmp->buffer, tmp->nbytes);
total_lines -= tmp->nlines;
}
@@ -581,6 +607,7 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
++tmp->nlines;
--n;
}
+ desired_pos += p - tmp->buffer;
xwrite_stdout (tmp->buffer, p - tmp->buffer);
}
@@ -591,6 +618,9 @@ free_lbuffers:
free (first);
first = tmp;
}
+
+ if (0 <= current_pos && elseek (fd, desired_pos, SEEK_SET, filename) < 0)
+ ok = false;
return ok;
}
@@ -714,10 +744,11 @@ elide_tail_lines_seekable (const char *pretty_filename, int fd,
static bool
elide_tail_lines_file (const char *filename, int fd, uintmax_t n_elide,
- off_t current_pos, off_t size)
+ struct stat const *st, off_t current_pos)
{
- if (size < 0)
- return elide_tail_lines_pipe (filename, fd, n_elide);
+ off_t size = st->st_size;
+ if (presume_input_pipe || size <= ST_BLKSIZE (*st))
+ return elide_tail_lines_pipe (filename, fd, n_elide, current_pos);
else
{
/* Find the offset, OFF, of the Nth newline from the end,
@@ -802,28 +833,24 @@ head (const char *filename, int fd, uintmax_t n_units, bool count_lines,
if (elide_from_end)
{
- off_t current_pos = -1, size = -1;
- if (! presume_input_pipe)
+ off_t current_pos = -1;
+ struct stat st;
+ if (fstat (fd, &st) != 0)
{
- struct stat st;
- if (fstat (fd, &st) != 0)
- {
- error (0, errno, _("cannot fstat %s"),
- quotearg_colon (filename));
- return false;
- }
- if (S_ISREG (st.st_mode))
- {
- size = st.st_size;
- current_pos = elseek (fd, 0, SEEK_CUR, filename);
- if (current_pos < 0)
- return false;
- }
+ error (0, errno, _("cannot fstat %s"),
+ quotearg_colon (filename));
+ return false;
+ }
+ if (! presume_input_pipe && usable_st_size (&st))
+ {
+ current_pos = elseek (fd, 0, SEEK_CUR, filename);
+ if (current_pos < 0)
+ return false;
}
if (count_lines)
- return elide_tail_lines_file (filename, fd, n_units, current_pos, size);
+ return elide_tail_lines_file (filename, fd, n_units, &st, current_pos);
else
- return elide_tail_bytes_file (filename, fd, n_units, current_pos, size);
+ return elide_tail_bytes_file (filename, fd, n_units, &st, current_pos);
}
if (count_lines)
return head_lines (filename, fd, n_units);
@@ -866,7 +893,7 @@ head_file (const char *filename, uintmax_t n_units, bool count_lines,
return ok;
}
-/* Convert a string of decimal digits, N_STRING, with an optional suffinx
+/* Convert a string of decimal digits, N_STRING, with an optional suffix
to an integral value. Upon successful conversion,
return that value. If it cannot be converted, give a diagnostic and exit.
COUNT_LINES indicates whether N_STRING is a number of bytes or a number
@@ -875,27 +902,9 @@ head_file (const char *filename, uintmax_t n_units, bool count_lines,
static uintmax_t
string_to_integer (bool count_lines, const char *n_string)
{
- strtol_error s_err;
- uintmax_t n;
-
- s_err = xstrtoumax (n_string, NULL, 10, &n, "bkKmMGTPEZY0");
-
- if (s_err == LONGINT_OVERFLOW)
- {
- error (EXIT_FAILURE, 0,
- _("%s: %s is so large that it is not representable"), n_string,
- count_lines ? _("number of lines") : _("number of bytes"));
- }
-
- if (s_err != LONGINT_OK)
- {
- error (EXIT_FAILURE, 0, "%s: %s", n_string,
- (count_lines
- ? _("invalid number of lines")
- : _("invalid number of bytes")));
- }
-
- return n;
+ return xdectoumax (n_string, 0, UINTMAX_MAX, "bkKmMGTPEZY0",
+ count_lines ? _("invalid number of lines")
+ : _("invalid number of bytes"), 0);
}
int
@@ -1049,8 +1058,8 @@ main (int argc, char **argv)
if ( ! count_lines && elide_from_end && OFF_T_MAX < n_units)
{
char umax_buf[INT_BUFSIZE_BOUND (n_units)];
- error (EXIT_FAILURE, 0, _("%s: number of bytes is too large"),
- umaxtostr (n_units, umax_buf));
+ error (EXIT_FAILURE, EOVERFLOW, "%s: %s", _("invalid number of bytes"),
+ quote (umaxtostr (n_units, umax_buf)));
}
file_list = (optind < argc
@@ -1066,5 +1075,5 @@ main (int argc, char **argv)
if (have_read_stdin && close (STDIN_FILENO) < 0)
error (EXIT_FAILURE, errno, "-");
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/hostid.c b/src/hostid.c
index 5b40eb01..b6ef86f6 100644
--- a/src/hostid.c
+++ b/src/hostid.c
@@ -1,6 +1,6 @@
/* print the hexadecimal identifier for the current host
- Copyright (C) 1997-2014 Free Software Foundation, Inc.
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -46,7 +46,7 @@ Print the numeric identifier (in hexadecimal) for the current host.\n\
"), program_name);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -84,5 +84,5 @@ main (int argc, char **argv)
printf ("%08x\n", id);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/hostname.c b/src/hostname.c
index bab51ae4..371a2e1d 100644
--- a/src/hostname.c
+++ b/src/hostname.c
@@ -1,5 +1,5 @@
/* hostname - set or print the name of current host system
- Copyright (C) 1994-2014 Free Software Foundation, Inc.
+ Copyright (C) 1994-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ Print or set the hostname of the current system.\n\
program_name, program_name);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -112,5 +112,5 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/id.c b/src/id.c
index ccd1e879..26f8e2d6 100644
--- a/src/id.c
+++ b/src/id.c
@@ -1,5 +1,5 @@
/* id -- print real and effective UIDs and GIDs
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -104,7 +104,7 @@ or (when USER omitted) for the current user.\n\
\n\
Without any OPTION, print some useful set of identified information.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -314,7 +314,7 @@ main (int argc, char **argv)
putchar (opt_zero ? '\0' : '\n');
IF_LINT (free (pw_name));
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* Convert a gid_t to string. Do not use this function directly.
diff --git a/src/install.c b/src/install.c
index c3424227..bfde21d6 100644
--- a/src/install.c
+++ b/src/install.c
@@ -1,5 +1,5 @@
/* install - copy files and set attributes
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -668,7 +668,7 @@ the VERSION_CONTROL environment variable. Here are the values:\n\
existing, nil numbered if numbered backups exist, simple otherwise\n\
simple, never always make simple backups\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -1042,5 +1042,5 @@ main (int argc, char **argv)
}
}
- exit (exit_status);
+ return exit_status;
}
diff --git a/src/ioblksize.h b/src/ioblksize.h
index 55aaeae1..1b919952 100644
--- a/src/ioblksize.h
+++ b/src/ioblksize.h
@@ -1,5 +1,5 @@
/* I/O block size definitions for coreutils
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/join.c b/src/join.c
index 5c26e78a..52e4b18b 100644
--- a/src/join.c
+++ b/src/join.c
@@ -1,5 +1,5 @@
/* join - join lines of two files on a common field
- Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ Copyright (C) 1991-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -194,8 +194,14 @@ Usage: %s [OPTION]... FILE1 FILE2\n\
program_name);
fputs (_("\
For each pair of input lines with identical join fields, write a line to\n\
-standard output. The default join field is the first, delimited\n\
-by whitespace. When FILE1 or FILE2 (not both) is -, read standard input.\n\
+standard output. The default join field is the first, delimited by whitespace.\
+\n\
+"), stdout);
+ fputs (_("\
+\n\
+When FILE1 or FILE2 (not both) is -, read standard input.\n\
+"), stdout);
+ fputs (_("\
\n\
-a FILENUM also print unpairable lines from file FILENUM, where\n\
FILENUM is 1 or 2, corresponding to FILE1 or FILE2\n\
@@ -239,7 +245,7 @@ Note, comparisons honor the rules specified by 'LC_COLLATE'.\n\
If the input is not sorted and some lines cannot be joined, a\n\
warning message will be given.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -1191,7 +1197,7 @@ main (int argc, char **argv)
error (EXIT_FAILURE, errno, "%s", g_names[1]);
if (issued_disorder_warning[0] || issued_disorder_warning[1])
- exit (EXIT_FAILURE);
+ return EXIT_FAILURE;
else
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/kill.c b/src/kill.c
index 724667e0..83016ed3 100644
--- a/src/kill.c
+++ b/src/kill.c
@@ -1,5 +1,5 @@
/* kill -- send a signal to a process
- Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ Copyright (C) 2002-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -99,7 +99,7 @@ or the exit status of a process terminated by a signal.\n\
PID is an integer; if negative it identifies a process group.\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -109,8 +109,8 @@ PID is an integer; if negative it identifies a process group.\n\
maximum name width is NAME_WIDTH, and SIGNAME is the name to print. */
static void
-print_table_row (unsigned int num_width, int signum,
- unsigned int name_width, char const *signame)
+print_table_row (int num_width, int signum,
+ int name_width, char const *signame)
{
char const *description = strsignal (signum);
printf ("%*d %-*s %s\n", num_width, signum, name_width, signame,
@@ -306,7 +306,7 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- exit (list
- ? list_signals (table, optind < argc ? argv + optind : NULL)
- : send_signals (signum, argv + optind));
+ return (list
+ ? list_signals (table, optind < argc ? argv + optind : NULL)
+ : send_signals (signum, argv + optind));
}
diff --git a/src/libstdbuf.c b/src/libstdbuf.c
index 1281b9de..255df7eb 100644
--- a/src/libstdbuf.c
+++ b/src/libstdbuf.c
@@ -1,5 +1,5 @@
/* libstdbuf -- a shared lib to preload to setup stdio buffering for a command
- Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Copyright (C) 2009-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,9 +18,7 @@
#include <config.h>
#include <stdio.h>
-#include <stdlib.h>
#include "system.h"
-#include "verify.h"
/* Note currently for glibc (2.3.5) the following call does not change
the buffer size, and more problematically does not give any indication
diff --git a/src/link.c b/src/link.c
index 9f18fe2e..bbd18292 100644
--- a/src/link.c
+++ b/src/link.c
@@ -1,5 +1,5 @@
/* link utility for GNU.
- Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Copyright (C) 2001-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ Usage: %s FILE1 FILE2\n\
stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -90,5 +90,5 @@ main (int argc, char **argv)
error (EXIT_FAILURE, errno, _("cannot create link %s to %s"),
quote_n (0, argv[optind + 1]), quote_n (1, argv[optind]));
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/ln.c b/src/ln.c
index 42bccfce..652103b1 100644
--- a/src/ln.c
+++ b/src/ln.c
@@ -1,5 +1,5 @@
/* 'ln' program to create links between files.
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -452,7 +452,7 @@ the VERSION_CONTROL environment variable. Here are the values:\n\
Using -s ignores -L and -P. Otherwise, the last option specified controls\n\
behavior when a TARGET is a symbolic link, defaulting to %s.\n\
"), LINK_FOLLOWS_SYMLINKS ? "-L" : "-P");
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -647,5 +647,5 @@ main (int argc, char **argv)
else
ok = do_link (file[0], file[1]);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/local.mk b/src/local.mk
index c0d04d68..eaeed08e 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -1,7 +1,7 @@
# Make coreutils programs. -*-Makefile-*-
# This is included by the top-level Makefile.am.
-## Copyright (C) 1990-2014 Free Software Foundation, Inc.
+## Copyright (C) 1990-2015 Free Software Foundation, Inc.
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@@ -278,7 +278,7 @@ src_uptime_LDADD += $(GETLOADAVG_LIBS)
# for various ACL functions
copy_ldadd += $(LIB_ACL)
-src_ls_LDADD += $(LIB_ACL)
+src_ls_LDADD += $(LIB_HAS_ACL)
# for various xattr functions
copy_ldadd += $(LIB_XATTR)
@@ -340,7 +340,14 @@ copy_sources = \
# confusion with the 'install' target. The install rule transforms 'ginstall'
# to install before applying any user-specified name transformations.
-transform = s/ginstall/install/; $(program_transform_name)
+# Don't apply prefix transformations to libstdbuf shared lib
+# as that's not generally needed, and we need to reference the
+# name directly in LD_PRELOAD etc. In general it's surprising
+# that $(transform) is applied to libexec at all given that is
+# for internal package naming, not privy to $(transform).
+
+transform = s/ginstall/install/;/libstdbuf/!$(program_transform_name)
+
src_ginstall_SOURCES = src/install.c src/prog-fprintf.c $(copy_sources) \
$(selinux_sources)
@@ -420,7 +427,8 @@ endif SINGLE_BINARY
CLEANFILES += src/coreutils_symlinks
src/coreutils_symlinks: Makefile
$(AM_V_GEN)touch $@
- $(AM_V_at)for i in $(single_binary_progs); do \
+ $(AM_V_at)for i in x $(single_binary_progs); do \
+ test $$i = x && continue; \
rm -f src/$$i$(EXEEXT) || exit $$?; \
$(LN_S) -s coreutils$(EXEEXT) src/$$i$(EXEEXT) || exit $$?; \
done
@@ -428,7 +436,8 @@ src/coreutils_symlinks: Makefile
CLEANFILES += src/coreutils_shebangs
src/coreutils_shebangs: Makefile
$(AM_V_GEN)touch $@
- $(AM_V_at)for i in $(single_binary_progs); do \
+ $(AM_V_at)for i in x $(single_binary_progs); do \
+ test $$i = x && continue; \
rm -f src/$$i$(EXEEXT) || exit $$?; \
printf '#!%s --coreutils-prog-shebang=%s\n' \
$(abs_top_builddir)/src/coreutils$(EXEEXT) $$i \
@@ -437,7 +446,8 @@ src/coreutils_shebangs: Makefile
done
clean-local:
- $(AM_V_at)for i in $(single_binary_progs); do \
+ $(AM_V_at)for i in x $(single_binary_progs); do \
+ test $$i = x && continue; \
rm -f src/$$i$(EXEEXT) || exit $$?; \
done
@@ -570,7 +580,8 @@ src/version.h: Makefile
DISTCLEANFILES += src/coreutils.h
src/coreutils.h: Makefile
$(AM_V_GEN)rm -f $@
- $(AM_V_at)for prog in $(single_binary_progs); do \
+ $(AM_V_at)for prog in x $(single_binary_progs); do \
+ test $$prog = x && continue; \
prog=`basename $$prog`; \
main=`echo $$prog | tr '[' '_'`; \
echo "SINGLE_BINARY_PROGRAM(\"$$prog\", $$main)"; \
diff --git a/src/logname.c b/src/logname.c
index 6afa1b50..070c9017 100644
--- a/src/logname.c
+++ b/src/logname.c
@@ -1,5 +1,5 @@
/* logname -- print user's login name
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -43,7 +43,7 @@ Print the name of the current user.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -72,15 +72,12 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- /* POSIX requires using getlogin (or equivalent code). */
+ /* POSIX requires using getlogin (or equivalent code) and prohibits
+ using a fallback technique. */
cp = getlogin ();
- if (cp)
- {
- puts (cp);
- exit (EXIT_SUCCESS);
- }
- /* POSIX prohibits using a fallback technique. */
+ if (! cp)
+ error (EXIT_FAILURE, 0, _("no login name"));
- error (0, 0, _("no login name"));
- exit (EXIT_FAILURE);
+ puts (cp);
+ return EXIT_SUCCESS;
}
diff --git a/src/longlong.h b/src/longlong.h
index 25116130..df909e97 100644
--- a/src/longlong.h
+++ b/src/longlong.h
@@ -1,6 +1,6 @@
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
-Copyright 1991-2014 Free Software Foundation, Inc.
+Copyright 1991-2015 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free
@@ -186,7 +186,7 @@ along with this file. If not, see http://www.gnu.org/licenses/. */
UDItype __m0 = (m0), __m1 = (m1); \
__asm__ ("umulh %r1,%2,%0" \
: "=r" (ph) \
- : "%rJ" (m0), "rI" (m1)); \
+ : "%rJ" (__m0), "rI" (__m1)); \
(pl) = __m0 * __m1; \
} while (0)
#endif
@@ -196,7 +196,7 @@ along with this file. If not, see http://www.gnu.org/licenses/. */
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
- (ph) = __UMULH (m0, m1); \
+ (ph) = __UMULH (__m0, __m1); \
(pl) = __m0 * __m1; \
} while (0)
#endif
@@ -279,7 +279,7 @@ long __MPN(count_leading_zeros) (UDItype);
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
- (ph) = _int_mult_upper (m0, m1); \
+ (ph) = _int_mult_upper (__m0, __m1); \
(pl) = __m0 * __m1; \
} while (0)
#ifndef LONGLONG_STANDALONE
@@ -344,9 +344,9 @@ long __MPN(count_leading_zeros) (UDItype);
#include <ia64intrin.h>
#define umul_ppmm(ph, pl, m0, m1) \
do { \
- UWtype _m0 = (m0), _m1 = (m1); \
- ph = _m64_xmahu (_m0, _m1, 0); \
- pl = _m0 * _m1; \
+ UWtype __m0 = (m0), __m1 = (m1); \
+ ph = _m64_xmahu (__m0, __m1, 0); \
+ pl = __m0 * __m1; \
} while (0)
#endif
#ifndef LONGLONG_STANDALONE
@@ -423,7 +423,8 @@ long __MPN(count_leading_zeros) (UDItype);
"rIJ" ((USItype) (bl)))
#endif
-#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32
+#if defined (__arm__) && (defined (__thumb2__) || !defined (__thumb__)) \
+ && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \
: "=r" (sh), "=&r" (sl) \
@@ -468,7 +469,37 @@ long __MPN(count_leading_zeros) (UDItype);
: "=r" (sh), "=&r" (sl) \
: "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC);\
} while (0)
-#if 1 || defined (__arm_m__) /* `M' series has widening multiply support */
+#if defined (__ARM_ARCH_2__) || defined (__ARM_ARCH_2A__) \
+ || defined (__ARM_ARCH_3__)
+#define umul_ppmm(xh, xl, a, b) \
+ do { \
+ register USItype __t0, __t1, __t2; \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+ " mov %2, %5, lsr #16\n" \
+ " mov %0, %6, lsr #16\n" \
+ " bic %3, %5, %2, lsl #16\n" \
+ " bic %4, %6, %0, lsl #16\n" \
+ " mul %1, %3, %4\n" \
+ " mul %4, %2, %4\n" \
+ " mul %3, %0, %3\n" \
+ " mul %0, %2, %0\n" \
+ " adds %3, %4, %3\n" \
+ " addcs %0, %0, #65536\n" \
+ " adds %1, %1, %3, lsl #16\n" \
+ " adc %0, %0, %3, lsr #16" \
+ : "=&r" ((USItype) (xh)), "=r" ((USItype) (xl)), \
+ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
+ : "r" ((USItype) (a)), "r" ((USItype) (b)) __CLOBBER_CC); \
+ } while (0)
+#define UMUL_TIME 20
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __r; \
+ (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
+#define UDIV_TIME 200
+#else /* ARMv4 or newer */
#define umul_ppmm(xh, xl, a, b) \
__asm__ ("umull %0,%1,%2,%3" : "=&r" (xl), "=&r" (xh) : "r" (a), "r" (b))
#define UMUL_TIME 5
@@ -484,48 +515,10 @@ long __MPN(count_leading_zeros) (UDItype);
#define UDIV_NEEDS_NORMALIZATION 1
#define UDIV_TIME 70
#endif /* LONGLONG_STANDALONE */
-#else
-#define umul_ppmm(xh, xl, a, b) \
- __asm__ ("%@ Inlined umul_ppmm\n" \
-" mov %|r0, %2, lsr #16\n" \
-" mov %|r2, %3, lsr #16\n" \
-" bic %|r1, %2, %|r0, lsl #16\n" \
-" bic %|r2, %3, %|r2, lsl #16\n" \
-" mul %1, %|r1, %|r2\n" \
-" mul %|r2, %|r0, %|r2\n" \
-" mul %|r1, %0, %|r1\n" \
-" mul %0, %|r0, %0\n" \
-" adds %|r1, %|r2, %|r1\n" \
-" addcs %0, %0, #65536\n" \
-" adds %1, %1, %|r1, lsl #16\n" \
-" adc %0, %0, %|r1, lsr #16" \
- : "=&r" (xh), "=r" (xl) \
- : "r" (a), "r" (b) \
- : "r0", "r1", "r2")
-#define UMUL_TIME 20
-#ifndef LONGLONG_STANDALONE
-#define udiv_qrnnd(q, r, n1, n0, d) \
- do { UWtype __r; \
- (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \
- (r) = __r; \
- } while (0)
-extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
-#define UDIV_TIME 200
-#endif /* LONGLONG_STANDALONE */
-#endif
-/* This is a bizarre test, but GCC doesn't define any useful common symbol. */
-#if defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__) || \
- defined (__ARM_ARCH_5E__) || defined (__ARM_ARCH_5TE__)|| \
- defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__) || \
- defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6Z__) || \
- defined (__ARM_ARCH_6ZK__)|| defined (__ARM_ARCH_6T2__)|| \
- defined (__ARM_ARCH_6M__) || defined (__ARM_ARCH_7__) || \
- defined (__ARM_ARCH_7A__) || defined (__ARM_ARCH_7R__) || \
- defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
-#define count_leading_zeros(count, x) \
- __asm__ ("clz\t%0, %1" : "=r" (count) : "r" (x))
+#endif /* defined(__ARM_ARCH_2__) ... */
+#define count_leading_zeros(count, x) count_leading_zeros_gcc_clz(count, x)
+#define count_trailing_zeros(count, x) count_trailing_zeros_gcc_ctz(count, x)
#define COUNT_LEADING_ZEROS_0 32
-#endif
#endif /* __arm__ */
#if defined (__aarch64__) && W_TYPE_SIZE == 64
@@ -534,21 +527,21 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \
: "=r" (sh), "=&r" (sl) \
- : "rZ" (ah), "rZ" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC)
+ : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
: "=r,r" (sh), "=&r,&r" (sl) \
- : "rZ,rZ" (ah), "rZ,rZ" (bh), "r,Z" (al), "rI,r" (bl) __CLOBBER_CC)
+ : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \
+ "r,Z" ((UDItype)(al)), "rI,r" ((UDItype)(bl)) __CLOBBER_CC)
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("umulh\t%0, %1, %2" : "=r" (ph) : "r" (m0), "r" (m1)); \
+ __asm__ ("umulh\t%0, %1, %2" : "=r" (ph) : "r" (__m0), "r" (__m1)); \
(pl) = __m0 * __m1; \
} while (0)
-#define count_leading_zeros(count, x) \
- __asm__ ("clz\t%0, %1" : "=r" (count) : "r" (x))
-#define count_trailing_zeros(count, x) \
- __asm__ ("rbit\t%0, %1\n\tclz\t%0, %0" : "=r" (count) : "r" (x))
+#define count_leading_zeros(count, x) count_leading_zeros_gcc_clz(count, x)
+#define count_trailing_zeros(count, x) count_trailing_zeros_gcc_ctz(count, x)
#define COUNT_LEADING_ZEROS_0 64
#endif /* __aarch64__ */
@@ -853,6 +846,8 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
#endif
#endif
+/* On x86 and x86_64, every asm implicitly clobbers "flags" and "fpsr",
+ so we don't need __CLOBBER_CC. */
#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addl %5,%k1\n\tadcl %3,%k0" \
@@ -1218,7 +1213,7 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
w0 = __ll; \
} while (0)
#endif
-#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7)
+#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7) && !defined (__clang__)
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("multu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v))
#endif
@@ -1241,14 +1236,17 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
w0 = __ll; \
} while (0)
#endif
-#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7)
+#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7) && !defined (__clang__)
#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("dmultu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v))
+ __asm__ ("dmultu %2,%3" \
+ : "=l" (w0), "=h" (w1) \
+ : "d" ((UDItype)(u)), "d" ((UDItype)(v)))
#endif
#if !defined (umul_ppmm)
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("dmultu %2,%3\n\tmflo %0\n\tmfhi %1" \
- : "=d" (w0), "=d" (w1) : "d" (u), "d" (v))
+ : "=d" (w0), "=d" (w1) \
+ : "d" ((UDItype)(u)), "d" ((UDItype)(v)))
#endif
#define UMUL_TIME 20
#define UDIV_TIME 140
@@ -1394,14 +1392,19 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
do { \
if (__builtin_constant_p (bh) && (bh) == 0) \
__asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
__asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl))); \
else \
__asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3" \
- : "=r" (sh), "=&r" (sl) \
- : "r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl))); \
} while (0)
/* We use "*rI" for the constant operand here, since with just "I", gcc barfs.
This might seem strange, but gcc folds away the dead code late. */
@@ -1410,37 +1413,55 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
if (__builtin_constant_p (bl) && bl > -0x8000 && bl <= 0x8000) { \
if (__builtin_constant_p (ah) && (ah) == 0) \
__asm__ ("addic %1,%3,%4\n\tsubfze %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "*rI" (-bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
__asm__ ("addic %1,%3,%4\n\tsubfme %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "*rI" (-bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
else if (__builtin_constant_p (bh) && (bh) == 0) \
__asm__ ("addic %1,%3,%4\n\taddme %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "*rI" (-bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
__asm__ ("addic %1,%3,%4\n\taddze %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "*rI" (-bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
else \
__asm__ ("addic %1,%4,%5\n\tsubfe %0,%3,%2" \
: "=r" (sh), "=&r" (sl) \
- : "r" (ah), "r" (bh), "rI" (al), "*rI" (-bl)); \
+ : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl)))); \
} else { \
if (__builtin_constant_p (ah) && (ah) == 0) \
__asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
__asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) == 0) \
__asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
__asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl)); \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
else \
__asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \
: "=r" (sh), "=&r" (sl) \
- : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
+ : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl))); \
} \
} while (0)
#endif /* ! _LONG_LONG_LIMB */
@@ -1460,7 +1481,7 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (__m0), "r" (__m1)); \
(pl) = __m0 * __m1; \
} while (0)
#endif
@@ -1468,7 +1489,7 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
#define smul_ppmm(ph, pl, m0, m1) \
do { \
DItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (__m0), "r" (__m1)); \
(pl) = __m0 * __m1; \
} while (0)
#define SMUL_TIME 14 /* ??? */
@@ -1745,18 +1766,20 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
"addcc %r4,%5,%1\n" \
" addccc %r6,%7,%%g0\n" \
" addc %r2,%3,%0" \
- : "=r" (sh), "=&r" (sl) \
- : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl), \
- "%rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" ((UDItype)(ah)), "rI" ((UDItype)(bh)), \
+ "%rJ" ((UDItype)(al)), "rI" ((UDItype)(bl)), \
+ "%rJ" ((UDItype)(al) >> 32), "rI" ((UDItype)(bl) >> 32) \
__CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ( \
"subcc %r4,%5,%1\n" \
" subccc %r6,%7,%%g0\n" \
" subc %r2,%3,%0" \
- : "=r" (sh), "=&r" (sl) \
- : "rJ" (ah), "rI" (bh), "rJ" (al), "rI" (bl), \
- "rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" ((UDItype)(ah)), "rI" ((UDItype)(bh)), \
+ "rJ" ((UDItype)(al)), "rI" ((UDItype)(bl)), \
+ "rJ" ((UDItype)(al) >> 32), "rI" ((UDItype)(bl) >> 32) \
__CLOBBER_CC)
#if __VIS__ >= 0x300
#undef add_ssaaaa
@@ -1765,7 +1788,8 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
"addcc %r4, %5, %1\n" \
" addxc %r2, %r3, %0" \
: "=r" (sh), "=&r" (sl) \
- : "rJ" (ah), "rJ" (bh), "%rJ" (al), "rI" (bl) __CLOBBER_CC)
+ : "rJ" ((UDItype)(ah)), "rJ" ((UDItype)(bh)), \
+ "%rJ" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC)
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
@@ -1776,6 +1800,8 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
} while (0)
#define count_leading_zeros(count, x) \
__asm__ ("lzd\t%1,%0" : "=r" (count) : "r" (x))
+/* Needed by count_leading_zeros_32 in sparc64.h. */
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
#endif
#endif
@@ -1870,13 +1896,19 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
#endif
+#if defined (__cplusplus)
+#define __longlong_h_C "C"
+#else
+#define __longlong_h_C
+#endif
+
/* Use mpn_umul_ppmm or mpn_udiv_qrnnd functions, if they exist. The "_r"
forms have "reversed" arguments, meaning the pointer is last, which
sometimes allows better parameter passing, in particular on 64-bit
hppa. */
#define mpn_umul_ppmm __MPN(umul_ppmm)
-extern UWtype mpn_umul_ppmm (UWtype *, UWtype, UWtype);
+extern __longlong_h_C UWtype mpn_umul_ppmm (UWtype *, UWtype, UWtype);
#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm \
&& ! defined (LONGLONG_STANDALONE)
@@ -1889,7 +1921,7 @@ extern UWtype mpn_umul_ppmm (UWtype *, UWtype, UWtype);
#endif
#define mpn_umul_ppmm_r __MPN(umul_ppmm_r)
-extern UWtype mpn_umul_ppmm_r (UWtype, UWtype, UWtype *);
+extern __longlong_h_C UWtype mpn_umul_ppmm_r (UWtype, UWtype, UWtype *);
#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm_r \
&& ! defined (LONGLONG_STANDALONE)
@@ -1902,7 +1934,7 @@ extern UWtype mpn_umul_ppmm_r (UWtype, UWtype, UWtype *);
#endif
#define mpn_udiv_qrnnd __MPN(udiv_qrnnd)
-extern UWtype mpn_udiv_qrnnd (UWtype *, UWtype, UWtype, UWtype);
+extern __longlong_h_C UWtype mpn_udiv_qrnnd (UWtype *, UWtype, UWtype, UWtype);
#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd \
&& ! defined (LONGLONG_STANDALONE)
@@ -1916,7 +1948,7 @@ extern UWtype mpn_udiv_qrnnd (UWtype *, UWtype, UWtype, UWtype);
#endif
#define mpn_udiv_qrnnd_r __MPN(udiv_qrnnd_r)
-extern UWtype mpn_udiv_qrnnd_r (UWtype, UWtype, UWtype, UWtype *);
+extern __longlong_h_C UWtype mpn_udiv_qrnnd_r (UWtype, UWtype, UWtype, UWtype *);
#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd_r \
&& ! defined (LONGLONG_STANDALONE)
diff --git a/src/ls.c b/src/ls.c
index cd5996eb..6860dd41 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -1,5 +1,5 @@
/* 'dir', 'vdir' and 'ls' directory listing programs for GNU.
- Copyright (C) 1985-2014 Free Software Foundation, Inc.
+ Copyright (C) 1985-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -105,6 +105,7 @@
#include "stat-size.h"
#include "stat-time.h"
#include "strftime.h"
+#include "xdectoint.h"
#include "xstrtol.h"
#include "areadlink.h"
#include "mbsalign.h"
@@ -284,6 +285,8 @@ static void queue_directory (char const *name, char const *realname,
static void sort_files (void);
static void parse_ls_color (void);
+static void getenv_quoting_style (void);
+
/* Initial size of hash table.
Most hierarchies are likely to be shallower than this. */
#define INITIAL_TABLE_SIZE 30
@@ -577,7 +580,7 @@ static struct bin_str color_indicator[] =
{
{ LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */
{ LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */
- { 0, NULL }, /* ec: End color (replaces lc+no+rc) */
+ { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */
{ LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */
{ 0, NULL }, /* no: Normal */
{ 0, NULL }, /* fi: File: default */
@@ -987,7 +990,7 @@ dev_ino_pop (void)
struct dev_ino *di;
int dev_ino_size = sizeof *di;
assert (dev_ino_size <= obstack_object_size (&dev_ino_obstack));
- obstack_blank (&dev_ino_obstack, -dev_ino_size);
+ obstack_blank_fast (&dev_ino_obstack, -dev_ino_size);
vdi = obstack_next_free (&dev_ino_obstack);
di = vdi;
return *di;
@@ -1511,7 +1514,7 @@ main (int argc, char **argv)
hash_free (active_dir_set);
}
- exit (exit_status);
+ return exit_status;
}
/* Set all the option flags according to the switches specified.
@@ -1577,20 +1580,7 @@ decode_switches (int argc, char **argv)
hide_patterns = NULL;
print_scontext = false;
- /* FIXME: put this in a function. */
- {
- char const *q_style = getenv ("QUOTING_STYLE");
- if (q_style)
- {
- int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals);
- if (0 <= i)
- set_quoting_style (NULL, quoting_style_vals[i]);
- else
- error (0, 0,
- _("ignoring invalid value of environment variable QUOTING_STYLE: %s"),
- quotearg (q_style));
- }
- }
+ getenv_quoting_style ();
line_length = 80;
{
@@ -1753,15 +1743,9 @@ decode_switches (int argc, char **argv)
break;
case 'w':
- {
- unsigned long int tmp_ulong;
- if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK
- || ! (0 < tmp_ulong && tmp_ulong <= SIZE_MAX))
- error (LS_FAILURE, 0, _("invalid line width: %s"),
- quotearg (optarg));
- line_length = tmp_ulong;
- break;
- }
+ line_length = xnumtoumax (optarg, 0, 1, SIZE_MAX, "",
+ _("invalid line width"), LS_FAILURE);
+ break;
case 'x':
format = horizontal;
@@ -1827,15 +1811,9 @@ decode_switches (int argc, char **argv)
break;
case 'T':
- {
- unsigned long int tmp_ulong;
- if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK
- || SIZE_MAX < tmp_ulong)
- error (LS_FAILURE, 0, _("invalid tab size: %s"),
- quotearg (optarg));
- tabsize = tmp_ulong;
- break;
- }
+ tabsize = xnumtoumax (optarg, 0, 0, SIZE_MAX, "",
+ _("invalid tab size"), LS_FAILURE);
+ break;
case 'U':
sort_type = sort_none;
@@ -2493,6 +2471,25 @@ parse_ls_color (void)
color_symlink_as_referent = true;
}
+/* Set the quoting style default if the environment variable
+ QUOTING_STYLE is set. */
+
+static void
+getenv_quoting_style (void)
+{
+ char const *q_style = getenv ("QUOTING_STYLE");
+ if (q_style)
+ {
+ int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals);
+ if (0 <= i)
+ set_quoting_style (NULL, quoting_style_vals[i]);
+ else
+ error (0, 0,
+ _("ignoring invalid value of environment variable QUOTING_STYLE: %s"),
+ quotearg (q_style));
+ }
+}
+
/* Set the exit status to report a failure. If SERIOUS, it is a
serious failure; otherwise, it is merely a minor problem. */
@@ -2831,10 +2828,7 @@ clear_files (void)
static bool
errno_unsupported (int err)
{
- return (err == EINVAL
- || err == ENOSYS
- || err == ENOTSUP
- || err == EOPNOTSUPP);
+ return (err == EINVAL || err == ENOSYS || is_ENOTSUP (err));
}
/* Cache *getfilecon failure, when it's trivial to do so.
@@ -2953,7 +2947,6 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
|| ((print_inode || format_needs_type)
&& (type == symbolic_link || type == unknown)
&& (dereference == DEREF_ALWAYS
- || (command_line_arg && dereference != DEREF_NEVER)
|| color_symlink_as_referent || check_symlink_color))
/* Command line dereferences are already taken care of by the above
assertion that the inode number is not yet known. */
@@ -3072,7 +3065,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
ls fail just because the file (even a command line argument)
isn't on the right type of file system. I.e., a getfilecon
failure isn't in the same class as a stat failure. */
- if (errno == ENOTSUP || errno == EOPNOTSUPP || errno == ENODATA)
+ if (is_ENOTSUP (errno) || errno == ENODATA)
err = 0;
}
@@ -3555,8 +3548,8 @@ static qsortFunc const sort_functions[][2][2][2] =
};
/* The number of sort keys is calculated as the sum of
- the number of elements in the sort_type enum (i.e. sort_numtypes)
- the number of elements in the time_type enum (i.e. time_numtypes) - 1
+ the number of elements in the sort_type enum (i.e., sort_numtypes)
+ the number of elements in the time_type enum (i.e., time_numtypes) - 1
This is because when sort_type==sort_time, we have up to
time_numtypes possible sort keys.
@@ -3668,7 +3661,8 @@ align_nstrftime (char *buf, size_t size, char const *fmt, struct tm const *tm,
the replacement is not done. A malloc here slows ls down by 2% */
char rpl_fmt[sizeof (abmon[0]) + 100];
const char *pb;
- if (required_mon_width && (pb = strstr (fmt, "%b")))
+ if (required_mon_width && (pb = strstr (fmt, "%b"))
+ && 0 <= tm->tm_mon && tm->tm_mon <= 11)
{
if (strlen (fmt) < (sizeof (rpl_fmt) - sizeof (abmon[0]) + 2))
{
@@ -4803,9 +4797,10 @@ Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n\
"), stdout);
fputs (_("\
-C list entries by columns\n\
- --color[=WHEN] colorize the output; WHEN can be 'never', 'auto',\
+ --color[=WHEN] colorize the output; WHEN can be 'always' (default\
+\n\
+ if omitted), 'auto', or 'never'; more info below\
\n\
- or 'always' (the default); more info below\n\
-d, --directory list directories themselves, not their contents\n\
-D, --dired generate output designed for Emacs' dired mode\n\
"), stdout);
@@ -4884,14 +4879,15 @@ Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n\
-s, --size print the allocated size of each file, in blocks\n\
"), stdout);
fputs (_("\
- -S sort by file size\n\
+ -S sort by file size, largest first\n\
--sort=WORD sort by WORD instead of name: none (-U), size (-S)\
,\n\
time (-t), version (-v), extension (-X)\n\
--time=WORD with -l, show time as WORD instead of default\n\
- modification time: atime or access or use (-u)\n\
+ modification time: atime or access or use (-u);\
+\n\
ctime or status (-c); also use specified time\n\
- as sort key if --sort=time\n\
+ as sort key if --sort=time (newest first)\n\
"), stdout);
fputs (_("\
--time-style=STYLE with -l, show times using style STYLE:\n\
@@ -4912,7 +4908,7 @@ Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n\
fputs (_("\
-u with -lt: sort by, and show, access time;\n\
with -l: show access time and sort by name;\n\
- otherwise: sort by access time\n\
+ otherwise: sort by access time, newest first\n\
-U do not sort; list entries in directory order\n\
-v natural sort of (version) numbers within text\n\
"), stdout);
@@ -4921,7 +4917,8 @@ Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n\
-x list entries by lines instead of by columns\n\
-X sort alphabetically by entry extension\n\
-Z, --context print any security context of each file\n\
- -1 list one file per line\n\
+ -1 list one file per line. Avoid '\\n' with -q or -b\
+\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -4940,7 +4937,7 @@ Exit status:\n\
1 if minor problems (e.g., cannot access subdirectory),\n\
2 if serious trouble (e.g., cannot access command-line argument).\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
diff --git a/src/make-prime-list.c b/src/make-prime-list.c
index c01b1200..0d5b614f 100644
--- a/src/make-prime-list.c
+++ b/src/make-prime-list.c
@@ -3,7 +3,7 @@
Contributed to the GNU project by Torbjörn Granlund and Niels Möller
Contains code from GNU MP.
-Copyright 2012-2014 Free Software Foundation, Inc.
+Copyright 2012-2015 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -131,7 +131,7 @@ output_primes (const struct prime *primes, unsigned nprimes)
abort ();
printf ("P (%u, %u,\n (", primes[i].p - p, d8);
print_wide_uint (primes[i].pinv, 0, wide_uint_bits);
- printf ("),\n UINTMAX_MAX / %d)\n", primes[i].p);
+ printf ("),\n UINTMAX_MAX / %u)\n", primes[i].p);
p = primes[i].p;
}
@@ -187,7 +187,7 @@ main (int argc, char **argv)
}
limit = atoi (argv[1]);
if (limit < 3)
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
/* Make limit odd */
if ( !(limit & 1))
@@ -211,12 +211,15 @@ main (int argc, char **argv)
for (j = (p*p - 3)/2; j < size; j+= p)
sieve[j] = 0;
- while (i < size && sieve[++i] == 0)
+ while (++i < size && sieve[i] == 0)
;
}
output_primes (prime_list, nprimes);
+ free (sieve);
+ free (prime_list);
+
if (ferror (stdout) + fclose (stdout))
{
fprintf (stderr, "write error: %s\n", strerror (errno));
diff --git a/src/md5sum.c b/src/md5sum.c
index cc6dd49e..bc2b7092 100644
--- a/src/md5sum.c
+++ b/src/md5sum.c
@@ -1,5 +1,5 @@
/* Compute checksums of files or strings.
- Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Copyright (C) 1995-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -164,18 +164,21 @@ usage (int status)
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
Print or check %s (%d-bit) checksums.\n\
-With no FILE, or when FILE is -, read standard input.\n\
-\n\
"),
program_name,
DIGEST_TYPE_STRING,
DIGEST_BITS);
+
+ emit_stdin_note ();
+
if (O_BINARY)
fputs (_("\
+\n\
-b, --binary read in binary mode (default unless reading tty stdin)\n\
"), stdout);
else
fputs (_("\
+\n\
-b, --binary read in binary mode\n\
"), stdout);
printf (_("\
@@ -206,11 +209,11 @@ The following four options are useful only when verifying checksums:\n\
printf (_("\
\n\
The sums are computed as described in %s. When checking, the input\n\
-should be a former output of this program. The default mode is to print\n\
-a line with checksum, a character indicating input mode ('*' for binary,\n\
-space for text), and name for each FILE.\n"),
+should be a former output of this program. The default mode is to print a\n\
+line with checksum, a space, a character indicating input mode ('*' for binary,\
+\n' ' for text or where binary is insignificant), and name for each FILE.\n"),
DIGEST_REFERENCE);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
@@ -874,5 +877,5 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, _("standard input"));
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/mkdir.c b/src/mkdir.c
index eb9693cc..ff51ae1e 100644
--- a/src/mkdir.c
+++ b/src/mkdir.c
@@ -1,5 +1,5 @@
/* mkdir -- make directories
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -75,7 +75,7 @@ Create the DIRECTORY(ies), if they do not already exist.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -151,23 +151,11 @@ static int
process_dir (char *dir, struct savewd *wd, void *options)
{
struct mkdir_options const *o = options;
- bool set_defaultcon = false;
/* If possible set context before DIR created. */
if (o->set_security_context)
{
- if (! o->make_ancestor_function)
- set_defaultcon = true;
- else
- {
- char *pdir = dir_name (dir);
- struct stat st;
- if (STREQ (pdir, ".")
- || (stat (pdir, &st) == 0 && S_ISDIR (st.st_mode)))
- set_defaultcon = true;
- free (pdir);
- }
- if (set_defaultcon && defaultcon (dir, S_IFDIR) < 0
+ if (! o->make_ancestor_function && defaultcon (dir, S_IFDIR) < 0
&& ! ignorable_ctx_err (errno))
error (0, errno, _("failed to set default creation context for %s"),
quote (dir));
@@ -184,7 +172,8 @@ process_dir (char *dir, struct savewd *wd, void *options)
final component of DIR is created. So for now, create the
final component with the context from previous component
and here we set the context for the final component. */
- if (ret == EXIT_SUCCESS && o->set_security_context && ! set_defaultcon)
+ if (ret == EXIT_SUCCESS && o->set_security_context
+ && o->make_ancestor_function)
{
if (! restorecon (last_component (dir), false, false)
&& ! ignorable_ctx_err (errno))
@@ -301,6 +290,6 @@ main (int argc, char **argv)
options.mode = S_IRWXUGO;
}
- exit (savewd_process_files (argc - optind, argv + optind,
- process_dir, &options));
+ return savewd_process_files (argc - optind, argv + optind,
+ process_dir, &options);
}
diff --git a/src/mkfifo.c b/src/mkfifo.c
index 415ae562..090656bd 100644
--- a/src/mkfifo.c
+++ b/src/mkfifo.c
@@ -1,5 +1,5 @@
/* mkfifo -- make fifo's (named pipes)
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -67,7 +67,7 @@ Create named pipes (FIFOs) with the given NAMEs.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -177,5 +177,5 @@ main (int argc, char **argv)
}
}
- exit (exit_status);
+ return exit_status;
}
diff --git a/src/mknod.c b/src/mknod.c
index 8f547e9c..73342ce2 100644
--- a/src/mknod.c
+++ b/src/mknod.c
@@ -1,5 +1,5 @@
/* mknod -- make special files
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -83,7 +83,7 @@ otherwise, as decimal. TYPE may be:\n\
p create a FIFO\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -94,7 +94,7 @@ main (int argc, char **argv)
mode_t newmode;
char const *specified_mode = NULL;
int optc;
- int expected_operands;
+ size_t expected_operands;
mode_t node_type;
char const *scontext = NULL;
bool set_security_context = false;
@@ -269,5 +269,5 @@ main (int argc, char **argv)
error (EXIT_FAILURE, errno, _("cannot set permissions of %s"),
quote (argv[optind]));
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/mktemp.c b/src/mktemp.c
index 2bd80bae..c2a449fa 100644
--- a/src/mktemp.c
+++ b/src/mktemp.c
@@ -1,5 +1,5 @@
/* Create a temporary file or directory, safely.
- Copyright (C) 2007-2014 Free Software Foundation, Inc.
+ Copyright (C) 2007-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -96,7 +96,7 @@ Files are created u+rw, and directories u+rwx, minus umask restrictions.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
@@ -345,5 +345,5 @@ main (int argc, char **argv)
free (template);
#endif
- exit (status);
+ return status;
}
diff --git a/src/mv.c b/src/mv.c
index 1db404ff..0bcc1bb6 100644
--- a/src/mv.c
+++ b/src/mv.c
@@ -1,5 +1,5 @@
/* mv -- move or rename files
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -107,7 +107,7 @@ cp_option_init (struct cp_options *x)
cp_options_default (x);
x->copy_as_regular = false; /* FIXME: maybe make this an option */
- x->reflink_mode = REFLINK_NEVER;
+ x->reflink_mode = REFLINK_AUTO;
x->dereference = DEREF_NEVER;
x->unlink_dest_before_opening = false;
x->unlink_dest_after_failed_open = false;
@@ -336,7 +336,7 @@ the VERSION_CONTROL environment variable. Here are the values:\n\
existing, nil numbered if numbered backups exist, simple otherwise\n\
simple, never always make simple backups\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -508,5 +508,5 @@ main (int argc, char **argv)
else
ok = movefile (file[0], file[1], false, &x);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/nice.c b/src/nice.c
index 488ef95a..121d1c09 100644
--- a/src/nice.c
+++ b/src/nice.c
@@ -1,5 +1,5 @@
/* nice -- run a program with modified niceness
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -85,7 +85,7 @@ With no COMMAND, print the current niceness. Niceness values range from\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -187,7 +187,7 @@ main (int argc, char **argv)
if (current_niceness == -1 && errno != 0)
error (EXIT_CANCELED, errno, _("cannot get niceness"));
printf ("%d\n", current_niceness);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
errno = 0;
@@ -209,14 +209,12 @@ main (int argc, char **argv)
encountered a write failure, there is no need to try calling
error() again. */
if (ferror (stderr))
- exit (EXIT_CANCELED);
+ return EXIT_CANCELED;
}
execvp (argv[i], &argv[i]);
- {
- int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
- error (0, errno, "%s", argv[i]);
- exit (exit_status);
- }
+ int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
+ error (0, errno, "%s", argv[i]);
+ return exit_status;
}
diff --git a/src/nl.c b/src/nl.c
index 982f468e..1132af39 100644
--- a/src/nl.c
+++ b/src/nl.c
@@ -1,5 +1,5 @@
/* nl -- number lines of files
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
#include "fadvise.h"
#include "linebuffer.h"
#include "quote.h"
-#include "xstrtol.h"
+#include "xdectoint.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "nl"
@@ -178,9 +178,9 @@ Usage: %s [OPTION]... [FILE]...\n\
program_name);
fputs (_("\
Write each FILE to standard output, with line numbers added.\n\
-With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -223,7 +223,7 @@ FORMAT is one of:\n\
rz right justified, leading zeros\n\
\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -497,53 +497,27 @@ main (int argc, char **argv)
}
break;
case 'v':
- if (xstrtoimax (optarg, NULL, 10, &starting_line_number, "")
- != LONGINT_OK)
- {
- error (0, 0, _("invalid starting line number: %s"),
- quote (optarg));
- ok = false;
- }
+ starting_line_number = xdectoimax (optarg, INTMAX_MIN, INTMAX_MAX, "",
+ _("invalid starting line number"),
+ 0);
break;
case 'i':
- if (! (xstrtoimax (optarg, NULL, 10, &page_incr, "") == LONGINT_OK
- && 0 < page_incr))
- {
- error (0, 0, _("invalid line number increment: %s"),
- quote (optarg));
- ok = false;
- }
+ page_incr = xdectoimax (optarg, 1, INTMAX_MAX, "",
+ _("invalid line number increment"), 0);
break;
case 'p':
reset_numbers = false;
break;
case 'l':
- if (! (xstrtoimax (optarg, NULL, 10, &blank_join, "") == LONGINT_OK
- && 0 < blank_join))
- {
- error (0, 0, _("invalid number of blank lines: %s"),
- quote (optarg));
- ok = false;
- }
+ blank_join = xdectoimax (optarg, 1, INTMAX_MAX, "",
+ _("invalid line number of blank lines"), 0);
break;
case 's':
separator_str = optarg;
break;
case 'w':
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
- {
- error (0, 0, _("invalid line number field width: %s"),
- quote (optarg));
- ok = false;
- }
- else
- {
- lineno_width = tmp_long;
- }
- }
+ lineno_width = xdectoimax (optarg, 1, INT_MAX, "",
+ _("invalid line number field width"), 0);
break;
case 'n':
if (STREQ (optarg, "ln"))
@@ -612,5 +586,5 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, "-");
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/nohup.c b/src/nohup.c
index eca1f512..8cdacedb 100644
--- a/src/nohup.c
+++ b/src/nohup.c
@@ -1,5 +1,5 @@
/* nohup -- run a command immune to hangups, with output to a non-tty
- Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Copyright (C) 2003-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -63,14 +63,14 @@ Run COMMAND, ignoring hangup signals.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (_("\n\
-If standard input is a terminal, redirect it from /dev/null.\n\
+If standard input is a terminal, redirect it from an unreadable file.\n\
If standard output is a terminal, append output to 'nohup.out' if possible,\n\
'$HOME/nohup.out' otherwise.\n\
If standard error is a terminal, redirect it to standard output.\n\
To save output to FILE, use '%s COMMAND > FILE'.\n"),
program_name);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -123,10 +123,8 @@ main (int argc, char **argv)
if (ignoring_input)
{
if (fd_reopen (STDIN_FILENO, "/dev/null", O_WRONLY, 0) < 0)
- {
- error (0, errno, _("failed to render standard input unusable"));
- exit (exit_internal_failure);
- }
+ error (exit_internal_failure, errno,
+ _("failed to render standard input unusable"));
if (!redirecting_stdout && !redirecting_stderr)
error (0, 0, _("ignoring input"));
}
@@ -164,7 +162,7 @@ main (int argc, char **argv)
if (in_home)
error (0, saved_errno2, _("failed to open %s"),
quote (in_home));
- exit (exit_internal_failure);
+ return exit_internal_failure;
}
file = in_home;
}
@@ -213,28 +211,23 @@ main (int argc, char **argv)
error() again, particularly since we may have just changed the
underlying fd out from under stderr. */
if (ferror (stderr))
- exit (exit_internal_failure);
+ return exit_internal_failure;
signal (SIGHUP, SIG_IGN);
- {
- int exit_status;
- int saved_errno;
- char **cmd = argv + optind;
-
- execvp (*cmd, cmd);
- exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
- saved_errno = errno;
-
- /* The execve failed. Output a diagnostic to stderr only if:
- - stderr was initially redirected to a non-tty, or
- - stderr was initially directed to a tty, and we
- can dup2 it to point back to that same tty.
- In other words, output the diagnostic if possible, but only if
- it will go to the original stderr. */
- if (dup2 (saved_stderr_fd, STDERR_FILENO) == STDERR_FILENO)
- error (0, saved_errno, _("failed to run command %s"), quote (*cmd));
-
- exit (exit_status);
- }
+ char **cmd = argv + optind;
+ execvp (*cmd, cmd);
+ int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
+ int saved_errno = errno;
+
+ /* The execve failed. Output a diagnostic to stderr only if:
+ - stderr was initially redirected to a non-tty, or
+ - stderr was initially directed to a tty, and we
+ can dup2 it to point back to that same tty.
+ In other words, output the diagnostic if possible, but only if
+ it will go to the original stderr. */
+ if (dup2 (saved_stderr_fd, STDERR_FILENO) == STDERR_FILENO)
+ error (0, saved_errno, _("failed to run command %s"), quote (*cmd));
+
+ return exit_status;
}
diff --git a/src/nproc.c b/src/nproc.c
index 9bfc8b39..63c78cd4 100644
--- a/src/nproc.c
+++ b/src/nproc.c
@@ -1,5 +1,5 @@
/* nproc - print the number of processors.
- Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Copyright (C) 2009-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
#include "error.h"
#include "nproc.h"
#include "quote.h"
-#include "xstrtol.h"
+#include "xdectoint.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "nproc"
@@ -67,7 +67,7 @@ which may be less than the number of online processors\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -102,11 +102,7 @@ main (int argc, char **argv)
break;
case IGNORE_OPTION:
- if (xstrtoul (optarg, NULL, 10, &ignore, "") != LONGINT_OK)
- {
- error (0, 0, _("%s: invalid number to ignore"), optarg);
- usage (EXIT_FAILURE);
- }
+ ignore = xdectoumax (optarg, 0, ULONG_MAX, "", _("invalid number"),0);
break;
default:
@@ -129,5 +125,5 @@ main (int argc, char **argv)
printf ("%lu\n", nproc);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/numfmt.c b/src/numfmt.c
index 206866ac..35c5c5b9 100644
--- a/src/numfmt.c
+++ b/src/numfmt.c
@@ -1,5 +1,5 @@
/* Reformat numbers like 11505426432 to the more human-readable 11G
- Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Copyright (C) 2012-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,6 +29,12 @@
#include "system.h"
#include "xstrtol.h"
#include "xstrndup.h"
+#include "gl_linked_list.h"
+#include "gl_xlist.h"
+
+#if HAVE_FPSETPREC
+# include <ieeefp.h>
+#endif
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "numfmt"
@@ -151,7 +157,7 @@ enum { DELIMITER_DEFAULT = CHAR_MAX + 1 };
/* Maximum number of digits we can safely handle
without precision loss, if scaling is 'none'. */
-enum { MAX_UNSCALED_DIGITS = 18 };
+enum { MAX_UNSCALED_DIGITS = LDBL_DIG };
/* Maximum number of digits we can work with.
This is equivalent to 999Y.
@@ -161,8 +167,8 @@ enum { MAX_ACCEPTABLE_DIGITS = 27 };
static enum scale_type scale_from = scale_none;
static enum scale_type scale_to = scale_none;
-static enum round_type _round = round_from_zero;
-static enum inval_type _invalid = inval_abort;
+static enum round_type round_style = round_from_zero;
+static enum inval_type inval_style = inval_abort;
static const char *suffix = NULL;
static uintmax_t from_unit_size = 1;
static uintmax_t to_unit_size = 1;
@@ -171,6 +177,7 @@ static char *padding_buffer = NULL;
static size_t padding_buffer_size = 0;
static long int padding_width = 0;
static long int zero_padding_width = 0;
+static long int user_precision = -1;
static const char *format_str = NULL;
static char *format_str_prefix = NULL;
static char *format_str_suffix = NULL;
@@ -182,7 +189,10 @@ static int conv_exit_code = EXIT_CONVERSION_WARNINGS;
/* auto-pad each line based on skipped whitespace. */
static int auto_padding = 0;
static mbs_align_t padding_alignment = MBS_ALIGN_RIGHT;
-static long int field = 1;
+static bool all_fields = false;
+static size_t all_fields_after = 0;
+static size_t all_fields_before = 0;
+static gl_list_t field_list;
static int delimiter = DELIMITER_DEFAULT;
/* if non-zero, the first 'header' lines from STDIN are skipped. */
@@ -382,30 +392,41 @@ simple_round_nearest (long double val)
return val < 0 ? val - 0.5 : val + 0.5;
}
-static inline intmax_t
+static inline long double _GL_ATTRIBUTE_CONST
simple_round (long double val, enum round_type t)
{
+ intmax_t rval;
+ intmax_t intmax_mul = val / INTMAX_MAX;
+ val -= (long double) INTMAX_MAX * intmax_mul;
+
switch (t)
{
case round_ceiling:
- return simple_round_ceiling (val);
+ rval = simple_round_ceiling (val);
+ break;
case round_floor:
- return simple_round_floor (val);
+ rval = simple_round_floor (val);
+ break;
case round_from_zero:
- return simple_round_from_zero (val);
+ rval = simple_round_from_zero (val);
+ break;
case round_to_zero:
- return simple_round_to_zero (val);
+ rval = simple_round_to_zero (val);
+ break;
case round_nearest:
- return simple_round_nearest (val);
+ rval = simple_round_nearest (val);
+ break;
default:
/* to silence the compiler - this should never happen. */
return 0;
}
+
+ return (long double) INTMAX_MAX * intmax_mul + rval;
}
enum simple_strtod_error
@@ -445,6 +466,7 @@ simple_strtod_int (const char *input_str,
long double val = 0;
unsigned int digits = 0;
+ bool found_digit = false;
if (*input_str == '-')
{
@@ -459,10 +481,14 @@ simple_strtod_int (const char *input_str,
{
int digit = (**endptr) - '0';
+ found_digit = true;
+
+ if (val || digit)
+ digits++;
+
if (digits > MAX_UNSCALED_DIGITS)
e = SSE_OK_PRECISION_LOSS;
- ++digits;
if (digits > MAX_ACCEPTABLE_DIGITS)
return SSE_OVERFLOW;
@@ -471,7 +497,8 @@ simple_strtod_int (const char *input_str,
++(*endptr);
}
- if (digits == 0)
+ if (! found_digit
+ && ! STREQ_LEN (*endptr, decimal_point, decimal_point_length))
return SSE_INVALID_NUMBER;
if (*negative)
val = -val;
@@ -513,7 +540,6 @@ simple_strtod_float (const char *input_str,
if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)
return e;
-
/* optional decimal point + fraction. */
if (STREQ_LEN (*endptr, decimal_point, decimal_point_length))
{
@@ -536,6 +562,8 @@ simple_strtod_float (const char *input_str,
val_frac = ((long double) val_frac) / powerld (10, exponent);
+ /* TODO: detect loss of precision (only really 18 digits
+ of precision across all digits (before and after '.')). */
if (value)
{
if (negative)
@@ -565,7 +593,7 @@ simple_strtod_float (const char *input_str,
Returns:
SSE_OK - valid number.
- SSE_OK_PRECISION_LOSS - if more than 18 digits were used.
+ SSE_OK_PRECISION_LOSS - if more than LDBL_DIG digits were used.
SSE_OVERFLOW - if more than 27 digits (999Y) were used.
SSE_INVALID_NUMBER - if no digits were found.
SSE_VALID_BUT_FORBIDDEN_SUFFIX
@@ -580,9 +608,12 @@ simple_strtod_human (const char *input_str,
/* 'scale_auto' is checked below. */
int scale_base = default_scale_base (allowed_scaling);
- devmsg ("simple_strtod_human:\n input string: %s\n "
- "locale decimal-point: %s\n",
- quote_n (0, input_str), quote_n (1, decimal_point));
+ devmsg ("simple_strtod_human:\n input string: %s\n"
+ " locale decimal-point: %s\n"
+ " MAX_UNSCALED_DIGITS: %d\n",
+ quote_n (0, input_str),
+ quote_n (1, decimal_point),
+ MAX_UNSCALED_DIGITS);
enum simple_strtod_error e =
simple_strtod_float (input_str, endptr, value, precision);
@@ -677,7 +708,7 @@ simple_strtod_fatal (enum simple_strtod_error err, char const *input_str)
}
- if (_invalid != inval_ignore)
+ if (inval_style != inval_ignore)
error (conv_exit_code, 0, gettext (msgid), quote (input_str));
}
@@ -729,18 +760,23 @@ double_to_human (long double val, int precision,
/* Normalize val to scale. */
unsigned int power = 0;
val = expld (val, scale_base, &power);
- devmsg (" scaled value to %Lf * %0.f ^ %d\n", val, scale_base, power);
+ devmsg (" scaled value to %Lf * %0.f ^ %u\n", val, scale_base, power);
/* Perform rounding. */
- int ten_or_less = 0;
- if (absld (val) < 10)
+ unsigned int power_adjust = 0;
+ if (user_precision != -1)
+ power_adjust = MIN (power * 3, user_precision);
+ else if (absld (val) < 10)
{
/* for values less than 10, we allow one decimal-point digit,
so adjust before rounding. */
- ten_or_less = 1;
- val *= 10;
+ power_adjust = 1;
}
+
+ val *= powerld (10, power_adjust);
val = simple_round (val, round);
+ val /= powerld (10, power_adjust);
+
/* two special cases after rounding:
1. a "999.99" can turn into 1000 - so scale down
2. a "9.99" can turn into 10 - so don't display decimal-point. */
@@ -749,20 +785,21 @@ double_to_human (long double val, int precision,
val /= scale_base;
power++;
}
- if (ten_or_less)
- val /= 10;
/* should "7.0" be printed as "7" ?
if removing the ".0" is preferred, enable the fourth condition. */
int show_decimal_point = (val != 0) && (absld (val) < 10) && (power > 0);
/* && (absld (val) > simple_round_floor (val))) */
- devmsg (" after rounding, value=%Lf * %0.f ^ %d\n", val, scale_base, power);
+ devmsg (" after rounding, value=%Lf * %0.f ^ %u\n", val, scale_base, power);
- stpcpy (pfmt, show_decimal_point ? ".1Lf%s" : ".0Lf%s");
+ stpcpy (pfmt, ".*Lf%s");
+
+ int prec = user_precision == -1 ? show_decimal_point : user_precision;
/* buf_size - 1 used here to ensure place for possible scale_IEC_I suffix. */
- num_size = snprintf (buf, buf_size - 1, fmt, val, suffix_power_char (power));
+ num_size = snprintf (buf, buf_size - 1, fmt, prec, val,
+ suffix_power_char (power));
if (num_size < 0 || num_size >= (int) buf_size - 1)
error (EXIT_FAILURE, 0,
_("failed to prepare value '%Lf' for printing"), val);
@@ -776,19 +813,48 @@ double_to_human (long double val, int precision,
}
/* Convert a string of decimal digits, N_STRING, with an optional suffix
- to an integral value. Upon successful conversion, return that value.
+ to an integral value. Suffixes are handled as with --from=auto.
+ Upon successful conversion, return that value.
If it cannot be converted, give a diagnostic and exit. */
static uintmax_t
unit_to_umax (const char *n_string)
{
strtol_error s_err;
+ const char *c_string = n_string;
+ char *t_string = NULL;
+ size_t n_len = strlen (n_string);
char *end = NULL;
uintmax_t n;
+ const char *suffixes = "KMGTPEZY";
+
+ /* Adjust suffixes so K=1000, Ki=1024, KiB=invalid. */
+ if (n_len && ! c_isdigit (n_string[n_len - 1]))
+ {
+ t_string = xmalloc (n_len + 2);
+ end = t_string + n_len - 1;
+ memcpy (t_string, n_string, n_len);
- s_err = xstrtoumax (n_string, &end, 10, &n, "KMGTPEZY");
+ if (*end == 'i' && 2 <= n_len && ! c_isdigit (*(end - 1)))
+ *end = '\0';
+ else
+ {
+ *++end = 'B';
+ *++end = '\0';
+ suffixes = "KMGTPEZY0";
+ }
+
+ c_string = t_string;
+ }
+
+ s_err = xstrtoumax (c_string, &end, 10, &n, suffixes);
if (s_err != LONGINT_OK || *end || n == 0)
- error (EXIT_FAILURE, 0, _("invalid unit size: %s"), quote (n_string));
+ {
+ free (t_string);
+ error (EXIT_FAILURE, 0, _("invalid unit size: %s"), quote (n_string));
+ }
+
+ free (t_string);
return n;
}
@@ -825,7 +891,8 @@ Reformat NUMBER(s), or the numbers from standard input if none are specified.\n\
-d, --delimiter=X use X instead of whitespace for field delimiter\n\
"), stdout);
fputs (_("\
- --field=N replace the number in input field N (default is 1)\n\
+ --field=FIELDS replace the numbers in these input fields (default=1)\n\
+ see FIELDS below\n\
"), stdout);
fputs (_("\
--format=FORMAT use printf style floating-point FORMAT;\n\
@@ -904,10 +971,21 @@ UNIT options:\n"), stdout);
...\n"), stdout);
fputs (_("\n\
+FIELDS supports cut(1) style field ranges:\n\
+ N N'th field, counted from 1\n\
+ N- from N'th field, to end of line\n\
+ N-M from N'th to M'th field (inclusive)\n\
+ -M from first to M'th field (inclusive)\n\
+ - all fields\n\
+Multiple fields/ranges can be separated with commas\n\
+"), stdout);
+
+ fputs (_("\n\
FORMAT must be suitable for printing one floating-point argument '%f'.\n\
Optional quote (%'f) will enable --grouping (if supported by current locale).\n\
Optional width value (%10f) will pad output. Optional zero (%010f) width\n\
will zero pad the number. Optional negative values (%-10f) will left align.\n\
+Optional precision (%.1f) will override the input determined precision.\n\
"), stdout);
printf (_("\n\
@@ -931,14 +1009,14 @@ Examples:\n\
-> \"1000\"\n\
$ echo 1K | %s --from=iec\n\
-> \"1024\"\n\
- $ df | %s --header --field 2 --to=si\n\
- $ ls -l | %s --header --field 5 --to=iec\n\
+ $ df -B1 | %s --header --field 2-4 --to=si\n\
+ $ ls -l | %s --header --field 5 --to=iec\n\
$ ls -lh | %s --header --field 5 --from=iec --padding=10\n\
$ ls -lh | %s --header --field 5 --from=iec --format %%10f\n"),
program_name, program_name, program_name,
program_name, program_name, program_name,
program_name, program_name, program_name);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -951,7 +1029,6 @@ Examples:\n\
Only a limited subset of printf(3) syntax is supported.
TODO:
- support .precision
support %e %g etc. rather than just %f
NOTES:
@@ -1005,7 +1082,7 @@ parse_format_string (char const *fmt)
if (endptr != (fmt + i) && pad != 0)
{
if (debug && padding_width && !(zero_padding && pad > 0))
- error (0, 0, _("--format padding overridding --padding"));
+ error (0, 0, _("--format padding overriding --padding"));
if (pad < 0)
{
@@ -1026,9 +1103,28 @@ parse_format_string (char const *fmt)
if (fmt[i] == '\0')
error (EXIT_FAILURE, 0, _("format %s ends in %%"), quote (fmt));
+ if (fmt[i] == '.')
+ {
+ i++;
+ errno = 0;
+ user_precision = strtol (fmt + i, &endptr, 10);
+ if (errno == ERANGE || user_precision < 0 || SIZE_MAX < user_precision
+ || isblank (fmt[i]) || fmt[i] == '+')
+ {
+ /* Note we disallow negative user_precision to be
+ consistent with printf(1). POSIX states that
+ negative precision is only supported (and ignored)
+ when used with '.*f'. glibc at least will malform
+ output when passed a direct negative precision. */
+ error (EXIT_FAILURE, 0,
+ _("invalid precision in format %s"), quote (fmt));
+ }
+ i = endptr - fmt;
+ }
+
if (fmt[i] != 'f')
error (EXIT_FAILURE, 0, _("invalid format %s,"
- " directive must be %%[0]['][-][N]f"),
+ " directive must be %%[0]['][-][N][.][N]f"),
quote (fmt));
i++;
suffix_pos = i;
@@ -1077,7 +1173,7 @@ parse_human_number (const char *str, long double /*output */ *value,
if (ptr && *ptr != '\0')
{
- if (_invalid != inval_ignore)
+ if (inval_style != inval_ignore)
error (conv_exit_code, 0, _("invalid suffix in input %s: %s"),
quote_n (0, str), quote_n (1, ptr));
e = SSE_INVALID_SUFFIX;
@@ -1094,27 +1190,39 @@ prepare_padded_number (const long double val, size_t precision)
/* Generate Output. */
char buf[128];
+ size_t precision_used = user_precision == -1 ? precision : user_precision;
+
/* Can't reliably print too-large values without auto-scaling. */
unsigned int x;
expld (val, 10, &x);
- if (scale_to == scale_none && x > MAX_UNSCALED_DIGITS)
+
+ if (scale_to == scale_none
+ && x + precision_used > MAX_UNSCALED_DIGITS)
{
- if (_invalid != inval_ignore)
- error (conv_exit_code, 0, _("value too large to be printed: '%Lg'"
- " (consider using --to)"), val);
+ if (inval_style != inval_ignore)
+ {
+ if (precision_used)
+ error (conv_exit_code, 0,
+ _("value/precision too large to be printed: '%Lg/%"PRIuMAX"'"
+ " (consider using --to)"), val, (uintmax_t)precision_used);
+ else
+ error (conv_exit_code, 0,
+ _("value too large to be printed: '%Lg'"
+ " (consider using --to)"), val);
+ }
return 0;
}
if (x > MAX_ACCEPTABLE_DIGITS - 1)
{
- if (_invalid != inval_ignore)
+ if (inval_style != inval_ignore)
error (conv_exit_code, 0, _("value too large to be printed: '%Lg'"
" (cannot handle values > 999Y)"), val);
return 0;
}
- double_to_human (val, precision, buf, sizeof (buf), scale_to, grouping,
- _round);
+ double_to_human (val, precision_used, buf, sizeof (buf),
+ scale_to, grouping, round_style);
if (suffix)
strncat (buf, suffix, sizeof (buf) - strlen (buf) -1);
@@ -1153,7 +1261,8 @@ print_padded_number (void)
/* Converts the TEXT number string to the requested representation,
and handles automatic suffix addition. */
static int
-process_suffixed_number (char *text, long double *result, size_t *precision)
+process_suffixed_number (char *text, long double *result,
+ size_t *precision, long int field)
{
if (suffix && strlen (text) > strlen (suffix))
{
@@ -1204,139 +1313,253 @@ process_suffixed_number (char *text, long double *result, size_t *precision)
return (e == SSE_OK || e == SSE_OK_PRECISION_LOSS);
}
-/* Skip the requested number of fields in the input string.
- Returns a pointer to the *delimiter* of the requested field,
- or a pointer to NUL (if reached the end of the string). */
-static inline char * _GL_ATTRIBUTE_PURE
-skip_fields (char *buf, int fields)
+typedef struct range_pair
{
- char *ptr = buf;
- if (delimiter != DELIMITER_DEFAULT)
- {
- if (*ptr == delimiter)
- fields--;
- while (*ptr && fields--)
- {
- while (*ptr && *ptr == delimiter)
- ++ptr;
- while (*ptr && *ptr != delimiter)
- ++ptr;
- }
- }
- else
- while (*ptr && fields--)
- {
- while (*ptr && isblank (to_uchar (*ptr)))
- ++ptr;
- while (*ptr && !isblank (to_uchar (*ptr)))
- ++ptr;
- }
- return ptr;
+ size_t lo;
+ size_t hi;
+} range_pair_t;
+
+static int
+sort_field (const void *elt1, const void *elt2)
+{
+ range_pair_t* rp1 = (range_pair_t*) elt1;
+ range_pair_t* rp2 = (range_pair_t*) elt2;
+
+ if (rp1->lo < rp2->lo)
+ return -1;
+
+ return rp1->lo > rp2->lo;
}
-/* Parse a delimited string, and extracts the requested field.
- NOTE: the input buffer is modified.
+static int
+match_field (const void *elt1, const void *elt2)
+{
+ range_pair_t* rp = (range_pair_t*) elt1;
+ size_t field = *(size_t*) elt2;
- TODO:
- Maybe support multiple fields, though can always pipe output
- into another numfmt to process other fields.
- Maybe default to processing all fields rather than just first?
+ if (rp->lo <= field && field <= rp->hi)
+ return 0;
+
+ if (rp->lo < field)
+ return -1;
+
+ return 1;
+}
- Output:
- _PREFIX, _DATA, _SUFFIX will point to the relevant positions
- in the input string, or be NULL if such a part doesn't exist. */
static void
-extract_fields (char *line, int _field,
- char ** _prefix, char ** _data, char ** _suffix)
+free_field (const void *elt)
{
- char *ptr = line;
- *_prefix = NULL;
- *_data = NULL;
- *_suffix = NULL;
+ void *p = (void *)elt;
+ free (p);
+}
- devmsg ("extracting Fields:\n input: %s\n field: %d\n",
- quote (line), _field);
+/* Add the specified fields to field_list.
+ The format recognized is similar to cut.
+ TODO: Refactor the more performant cut implementation
+ for use by both utilities. */
+static void
+parse_field_arg (char *arg)
+{
+
+ char *start, *end;
+ range_pair_t *rp;
+ size_t field_val;
+ size_t range_val = 0;
+
+ start = end = arg;
- if (field > 1)
+ if (STREQ (arg, "-"))
{
- /* skip the requested number of fields. */
- *_prefix = line;
- ptr = skip_fields (line, field - 1);
- if (*ptr == '\0')
- {
- /* not enough fields in the input - print warning? */
- devmsg (" TOO FEW FIELDS!\n prefix: %s\n", quote (*_prefix));
- return;
- }
+ all_fields = true;
+
+ return;
+ }
+
+ if (*start == '-')
+ {
+ /* range -M */
+ ++start;
+
+ all_fields_before = strtol (start, &end, 10);
+
+ if (start == end || all_fields_before <=0)
+ error (EXIT_FAILURE, 0, _("invalid field value %s"),
+ quote (start));
+
+ return;
+ }
+
+ field_list = gl_list_create_empty (GL_LINKED_LIST,
+ NULL, NULL, free_field, false);
+
+ while (*end != '\0') {
+ field_val = strtol (start, &end, 10);
+
+ if (start == end || field_val <=0)
+ error (EXIT_FAILURE, 0, _("invalid field value %s"),
+ quote (start));
+
+ if (! range_val)
+ {
+ /* field N */
+ rp = xmalloc (sizeof (*rp));
+ rp->lo = rp->hi = field_val;
+ gl_sortedlist_add (field_list, sort_field, rp);
+ }
+ else
+ {
+ /* range N-M
+ The last field was the start of the field range. The current
+ field is the end of the field range. We already added the
+ start field, so increment and add all the fields through
+ range end. */
+ if (field_val < range_val)
+ error (EXIT_FAILURE, 0, _("invalid decreasing range"));
+ rp = xmalloc (sizeof (*rp));
+ rp->lo = range_val + 1;
+ rp->hi = field_val;
+ gl_sortedlist_add (field_list, sort_field, rp);
+
+ range_val = 0;
+ }
+
+ switch (*end) {
+ case ',':
+ /* discrete field separator */
+ ++end;
+ start = end;
+ break;
- *ptr = '\0';
- ++ptr;
+ case '-':
+ /* field range separator */
+ ++end;
+ start = end;
+ range_val = field_val;
+ break;
}
+ }
- *_data = ptr;
- *_suffix = skip_fields (*_data, 1);
- if (**_suffix)
+ if (range_val)
{
- /* there is a suffix (i.e. the field is not the last on the line),
- so null-terminate the _data before it. */
- **_suffix = '\0';
- ++(*_suffix);
+ /* range N-
+ range_val was not reset indicating ARG
+ ended with a trailing '-' */
+ all_fields_after = range_val;
+ }
+}
+
+/* Return a pointer to the beginning of the next field in line.
+ The line pointer is moved to the end of the next field. */
+static char*
+next_field (char **line)
+{
+ char *field_start = *line;
+ char *field_end = field_start;
+
+ if (delimiter != DELIMITER_DEFAULT)
+ {
+ if (*field_start != delimiter)
+ {
+ while (*field_end && *field_end != delimiter)
+ ++field_end;
+ }
+ /* else empty field */
}
else
- *_suffix = NULL;
+ {
+ /* keep any space prefix in the returned field */
+ while (*field_end && isblank (to_uchar (*field_end)))
+ ++field_end;
- devmsg (" prefix: %s\n number: %s\n suffix: %s\n",
- quote_n (0, *_prefix ? *_prefix : ""),
- quote_n (1, *_data),
- quote_n (2, *_suffix ? *_suffix : ""));
+ while (*field_end && !isblank (to_uchar (*field_end)))
+ ++field_end;
+ }
+
+ *line = field_end;
+ return field_start;
}
+static bool
+include_field (size_t field)
+{
+ if (all_fields)
+ return true;
-/* Convert a number in a given line of text.
- NEWLINE specifies whether to output a '\n' for this "line". */
-static int
-process_line (char *line, bool newline)
+ if (all_fields_after && all_fields_after <= field)
+ return true;
+
+ if (all_fields_before && field <= all_fields_before)
+ return true;
+
+ /* default to field 1 */
+ if (! field_list)
+ return field == 1;
+
+ return gl_sortedlist_search (field_list, match_field, &field);
+}
+
+/* Convert and output the given field. If it is not included in the set
+ of fields to process just output the original */
+static bool
+process_field (char *text, size_t field)
{
- char *pre, *num, *suf;
long double val = 0;
size_t precision = 0;
- int valid_number = 0;
-
- extract_fields (line, field, &pre, &num, &suf);
- if (!num)
- if (_invalid != inval_ignore)
- error (conv_exit_code, 0, _("input line is too short, "
- "no numbers found to convert in field %ld"),
- field);
+ bool valid_number = true;
- if (num)
+ if (include_field (field))
{
- valid_number = process_suffixed_number (num, &val, &precision);
+ valid_number =
+ process_suffixed_number (text, &val, &precision, field);
+
if (valid_number)
valid_number = prepare_padded_number (val, precision);
+
+ if (valid_number)
+ print_padded_number ();
+ else
+ fputs (text, stdout);
}
+ else
+ fputs (text, stdout);
- if (pre)
- fputs (pre, stdout);
+ return valid_number;
+}
- if (pre && num)
- fputc ((delimiter == DELIMITER_DEFAULT) ? ' ' : delimiter, stdout);
+/* Convert number in a given line of text.
+ NEWLINE specifies whether to output a '\n' for this "line". */
+static int
+process_line (char *line, bool newline)
+{
+ char *next;
+ size_t field = 0;
+ bool valid_number = true;
- if (valid_number)
- {
- print_padded_number ();
- }
- else
- {
- if (num)
- fputs (num, stdout);
- }
+ while (true) {
+ ++field;
+ next = next_field (&line);
- if (suf)
- {
- fputc ((delimiter == DELIMITER_DEFAULT) ? ' ' : delimiter, stdout);
- fputs (suf, stdout);
- }
+ if (*line != '\0')
+ {
+ /* nul terminate the current field string and process */
+ *line = '\0';
+
+ if (! process_field (next, field))
+ valid_number = false;
+
+ fputc ((delimiter == DELIMITER_DEFAULT) ?
+ ' ' : delimiter, stdout);
+ ++line;
+ }
+ else
+ {
+ /* end of the line, process the last field and finish */
+ if (! process_field (next, field))
+ valid_number = false;
+
+ break;
+ }
+ }
if (newline)
putchar ('\n');
@@ -1355,6 +1578,11 @@ main (int argc, char **argv)
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
+#if HAVE_FPSETPREC
+ /* Enabled extended precision if needed. */
+ fpsetprec (FP_PE);
+#endif
+
decimal_point = nl_langinfo (RADIXCHAR);
if (decimal_point == NULL || strlen (decimal_point) == 0)
decimal_point = ".";
@@ -1390,7 +1618,7 @@ main (int argc, char **argv)
break;
case ROUND_OPTION:
- _round = XARGMATCH ("--round", optarg, round_args, round_types);
+ round_style = XARGMATCH ("--round", optarg, round_args, round_types);
break;
case GROUPING_OPTION:
@@ -1412,10 +1640,12 @@ main (int argc, char **argv)
break;
case FIELD_OPTION:
- if (xstrtol (optarg, NULL, 10, &field, "") != LONGINT_OK
- || field <= 0)
- error (EXIT_FAILURE, 0, _("invalid field value %s"),
- quote (optarg));
+ if (all_fields || all_fields_before || all_fields_after || field_list)
+ {
+ error (EXIT_FAILURE, 0,
+ _("multiple field specifications"));
+ }
+ parse_field_arg (optarg);
break;
case 'd':
@@ -1458,7 +1688,8 @@ main (int argc, char **argv)
break;
case INVALID_OPTION:
- _invalid = XARGMATCH ("--invalid", optarg, inval_args, inval_types);
+ inval_style = XARGMATCH ("--invalid", optarg,
+ inval_args, inval_types);
break;
case_GETOPT_HELP_CHAR;
@@ -1492,7 +1723,7 @@ main (int argc, char **argv)
setup_padding_buffer (padding_width);
auto_padding = (padding_width == 0 && delimiter == DELIMITER_DEFAULT);
- if (_invalid != inval_abort)
+ if (inval_style != inval_abort)
conv_exit_code = 0;
if (argc > optind)
@@ -1526,17 +1757,22 @@ main (int argc, char **argv)
error (0, errno, _("error reading input"));
}
+#ifdef lint
free (padding_buffer);
free (format_str_prefix);
free (format_str_suffix);
+ if (field_list)
+ gl_list_free (field_list);
+#endif
if (debug && !valid_numbers)
error (0, 0, _("failed to convert some of the input numbers"));
int exit_status = EXIT_SUCCESS;
- if (!valid_numbers && _invalid != inval_warn && _invalid != inval_ignore)
+ if (!valid_numbers
+ && inval_style != inval_warn && inval_style != inval_ignore)
exit_status = EXIT_CONVERSION_WARNINGS;
- exit (exit_status);
+ return exit_status;
}
diff --git a/src/od.c b/src/od.c
index 7bc0e2a8..0ca3ca78 100644
--- a/src/od.c
+++ b/src/od.c
@@ -1,5 +1,5 @@
/* od -- dump files in octal and other formats
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
#include "error.h"
#include "ftoastr.h"
#include "quote.h"
+#include "stat-size.h"
#include "xfreopen.h"
#include "xprintf.h"
#include "xstrtol.h"
@@ -327,10 +328,12 @@ Usage: %s [OPTION]... [FILE]...\n\
Write an unambiguous representation, octal bytes by default,\n\
of FILE to standard output. With more than one FILE argument,\n\
concatenate them in the listed order to form the input.\n\
-With no FILE, or when FILE is -, read standard input.\n\
-\n\
"), stdout);
+
+ emit_stdin_note ();
+
fputs (_("\
+\n\
If first and second call formats both apply, the second format is assumed\n\
if the last operand begins with + or (if there are 2 operands) a digit.\n\
An OFFSET operand means -j OFFSET. LABEL is the pseudo-address\n\
@@ -414,7 +417,7 @@ BYTES is hex with 0x or 0X prefix, and may have a multiplier suffix:\n\
M 1024*1024\n\
and so on for G, T, P, E, Z, Y.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -1034,9 +1037,11 @@ skip (uintmax_t n_skip)
If the number of bytes left to skip is larger than
the size of the current file, we can decrement n_skip
and go on to the next file. Skip this optimization also
- when st_size is 0, because some kernels report that
- nonempty files in /proc have st_size == 0. */
- if (S_ISREG (file_stats.st_mode) && 0 < file_stats.st_size)
+ when st_size is no greater than the block size, because
+ some kernels report nonsense small file sizes for
+ proc-like file systems. */
+ if (usable_st_size (&file_stats)
+ && ST_BLKSIZE (file_stats) < file_stats.st_size)
{
if ((uintmax_t) file_stats.st_size < n_skip)
n_skip -= file_stats.st_size;
@@ -1052,6 +1057,7 @@ skip (uintmax_t n_skip)
}
/* If it's not a regular file with nonnegative size,
+ or if it's so small that it might be in a proc-like file system,
position the file pointer by reading. */
else
@@ -1067,10 +1073,15 @@ skip (uintmax_t n_skip)
n_skip -= n_bytes_read;
if (n_bytes_read != n_bytes_to_read)
{
- in_errno = errno;
- ok = false;
- n_skip = 0;
- break;
+ if (ferror (in_stream))
+ {
+ in_errno = errno;
+ ok = false;
+ n_skip = 0;
+ break;
+ }
+ if (feof (in_stream))
+ break;
}
}
}
@@ -1280,9 +1291,6 @@ read_block (size_t n, char *block, size_t *n_bytes_in_buffer)
*n_bytes_in_buffer = 0;
- if (n == 0)
- return true;
-
while (in_stream != NULL) /* EOF. */
{
size_t n_needed;
@@ -1781,7 +1789,7 @@ main (int argc, char **argv)
}
if (!ok)
- exit (EXIT_FAILURE);
+ return EXIT_FAILURE;
if (flag_dump_strings && n_specs > 0)
error (EXIT_FAILURE, 0,
@@ -1953,7 +1961,8 @@ main (int argc, char **argv)
}
#ifdef DEBUG
- printf ("lcm=%d, width_per_block=%zu\n", l_c_m, width_per_block);
+ printf ("lcm=%d, width_per_block=%"PRIuMAX"\n", l_c_m,
+ (uintmax_t) width_per_block);
for (i = 0; i < n_specs; i++)
{
int fields_per_block = bytes_per_block / width_bytes[spec[i].size];
@@ -1972,5 +1981,5 @@ cleanup:
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, _("standard input"));
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/operand2sig.c b/src/operand2sig.c
index eb40f364..bc3b2279 100644
--- a/src/operand2sig.c
+++ b/src/operand2sig.c
@@ -1,5 +1,5 @@
/* operand2sig.c -- common function for parsing signal specifications
- Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/operand2sig.h b/src/operand2sig.h
index 04d27d1a..9babe6ad 100644
--- a/src/operand2sig.h
+++ b/src/operand2sig.h
@@ -1,6 +1,6 @@
/* operand2sig.h -- prototype for signal specification function
- Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/paste.c b/src/paste.c
index 3663aaf6..7a5b5d7a 100644
--- a/src/paste.c
+++ b/src/paste.c
@@ -1,5 +1,5 @@
/* paste - merge lines of files
- Copyright (C) 1997-2014 Free Software Foundation, Inc.
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
Copyright (C) 1984 David M. Ihnat
This program is free software: you can redistribute it and/or modify
@@ -235,7 +235,7 @@ paste_parallel (size_t nfiles, char **fnamptr)
{
int chr IF_LINT ( = 0); /* Input character. */
int err IF_LINT ( = 0); /* Input errno value. */
- size_t line_length = 0; /* Number of chars in line. */
+ bool sometodo = false; /* Input chars to process. */
if (fileptr[i])
{
@@ -250,7 +250,7 @@ paste_parallel (size_t nfiles, char **fnamptr)
while (chr != EOF)
{
- line_length++;
+ sometodo = true;
if (chr == '\n')
break;
xputchar (chr);
@@ -259,7 +259,7 @@ paste_parallel (size_t nfiles, char **fnamptr)
}
}
- if (line_length == 0)
+ if (! sometodo)
{
/* EOF, read error, or closed file.
If an EOF or error, close the file. */
@@ -439,9 +439,9 @@ Usage: %s [OPTION]... [FILE]...\n\
fputs (_("\
Write lines consisting of the sequentially corresponding lines from\n\
each FILE, separated by TABs, to standard output.\n\
-With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -451,7 +451,7 @@ With no FILE, or when FILE is -, read standard input.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
/* FIXME: add a couple of examples. */
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -518,5 +518,5 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, "-");
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/pathchk.c b/src/pathchk.c
index 4b3884fe..e05ecf7f 100644
--- a/src/pathchk.c
+++ b/src/pathchk.c
@@ -1,5 +1,5 @@
/* pathchk -- check whether file names are valid or portable
- Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ Copyright (C) 1991-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -96,7 +96,7 @@ Diagnose invalid or unportable file names.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -153,7 +153,7 @@ main (int argc, char **argv)
ok &= validate_file_name (argv[optind],
check_basic_portability, check_extra_portability);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* If FILE contains a component with a leading "-", report an error
diff --git a/src/pinky.c b/src/pinky.c
index c48e1705..71650bfa 100644
--- a/src/pinky.c
+++ b/src/pinky.c
@@ -1,5 +1,5 @@
/* GNU's pinky.
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -445,8 +445,7 @@ scan_entries (size_t n, const STRUCT_UTMP *utmp_buf,
int i;
for (i = 0; i < argc_names; i++)
- if (strncmp (UT_USER (utmp_buf), argv_names[i], UT_USER_SIZE)
- == 0)
+ if (STREQ_LEN (UT_USER (utmp_buf), argv_names[i], UT_USER_SIZE))
{
print_entry (utmp_buf);
break;
@@ -515,7 +514,7 @@ usage (int status)
A lightweight 'finger' program; print user information.\n\
The utmp file will be %s.\n\
"), UTMP_FILE);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -604,5 +603,5 @@ main (int argc, char **argv)
else
long_pinky (n_users, argv + optind);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/pr.c b/src/pr.c
index 1515b4a4..d79d84f1 100644
--- a/src/pr.c
+++ b/src/pr.c
@@ -1,5 +1,5 @@
/* pr -- convert text files for printing.
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -46,7 +46,7 @@
only one POSIX requirement has to be met:
The default n-separator should be a TAB. The consequence is a
different width between the number and the text if the output position
- of the separator changes, i.e. it depends upon the left margin used.
+ of the separator changes, i.e., it depends upon the left margin used.
That's not nice but easy-to-use together with the defaults of other
utilities, e.g. sort or cut. - Same as SunOS does.
- With multicolumn output
@@ -322,6 +322,7 @@
#include "stdio--.h"
#include "strftime.h"
#include "xstrtol.h"
+#include "xdectoint.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "pr"
@@ -424,6 +425,8 @@ static bool skip_to_page (uintmax_t page);
static void print_header (void);
static void pad_across_to (int position);
static void add_line_number (COLUMN *p);
+static void getoptnum (const char *n_str, int min, int *num,
+ const char *errfmt);
static void getoptarg (char *arg, char switch_char, char *character,
int *number);
static void print_files (int number_of_files, char **av);
@@ -435,7 +438,7 @@ static void init_store_cols (void);
static void store_columns (void);
static void balance (int total_stored);
static void store_char (char c);
-static void pad_down (int lines);
+static void pad_down (unsigned int lines);
static void read_rest_of_line (COLUMN *p);
static void skip_read (COLUMN *p, int column_number);
static void print_char (char c);
@@ -768,12 +771,12 @@ static struct option const long_options[] =
/* Return the number of columns that have either an open file or
stored lines. */
-static int _GL_ATTRIBUTE_PURE
+static unsigned int _GL_ATTRIBUTE_PURE
cols_ready_to_print (void)
{
COLUMN *q;
- int i;
- int n;
+ unsigned int i;
+ unsigned int n;
n = 0;
for (q = column_vector, i = 0; i < columns; ++q, ++i)
@@ -820,18 +823,12 @@ first_last_page (int oi, char c, char const *pages)
/* Parse column count string S, and if it's valid (1 or larger and
within range of the type of 'columns') set the global variables
- columns and explicit_columns and return true.
- Otherwise, exit with a diagnostic. */
+ columns and explicit_columns. Otherwise, exit with a diagnostic. */
+
static void
parse_column_count (char const *s)
{
- long int tmp_long;
- if (xstrtol (s, NULL, 10, &tmp_long, "") != LONGINT_OK
- || !(1 <= tmp_long && tmp_long <= INT_MAX))
- error (EXIT_FAILURE, 0,
- _("invalid number of columns: %s"), quote (s));
-
- columns = tmp_long;
+ getoptnum (s, 1, &columns, _("invalid number of columns"));
explicit_columns = true;
}
@@ -966,18 +963,9 @@ main (int argc, char **argv)
join_lines = true;
break;
case 'l':
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
- {
- error (EXIT_FAILURE, 0,
- _("'-l PAGE_LENGTH' invalid number of lines: %s"),
- quote (optarg));
- }
- lines_per_page = tmp_long;
- break;
- }
+ getoptnum (optarg, 1, &lines_per_page,
+ _("'-l PAGE_LENGTH' invalid number of lines"));
+ break;
case 'm':
parallel_files = true;
storing_columns = false;
@@ -990,28 +978,13 @@ main (int argc, char **argv)
break;
case 'N':
skip_count = false;
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long > INT_MAX)
- {
- error (EXIT_FAILURE, 0,
- _("'-N NUMBER' invalid starting line number: %s"),
- quote (optarg));
- }
- start_line_num = tmp_long;
- break;
- }
+ getoptnum (optarg, INT_MIN, &start_line_num,
+ _("'-N NUMBER' invalid starting line number"));
+ break;
case 'o':
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long < 0 || tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0,
- _("'-o MARGIN' invalid line offset: %s"), quote (optarg));
- chars_per_margin = tmp_long;
- break;
- }
+ getoptnum (optarg, 0, &chars_per_margin,
+ _("'-o MARGIN' invalid line offset"));
+ break;
case 'r':
ignore_failed_opens = true;
break;
@@ -1045,29 +1018,19 @@ main (int argc, char **argv)
old_options = true;
old_w = true;
{
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0,
- _("'-w PAGE_WIDTH' invalid number of characters: %s"),
- quote (optarg));
- if (!truncate_lines)
- chars_per_line = tmp_long;
- break;
+ int tmp_cpl;
+ getoptnum (optarg, 1, &tmp_cpl,
+ _("'-w PAGE_WIDTH' invalid number of characters"));
+ if (! truncate_lines)
+ chars_per_line = tmp_cpl;
}
+ break;
case 'W':
old_w = false; /* dominates -w */
truncate_lines = true;
- {
- long int tmp_long;
- if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
- error (EXIT_FAILURE, 0,
- _("'-W PAGE_WIDTH' invalid number of characters: %s"),
- quote (optarg));
- chars_per_line = tmp_long;
- break;
- }
+ getoptnum (optarg, 1, &chars_per_line,
+ _("'-W PAGE_WIDTH' invalid number of characters"));
+ break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
@@ -1170,9 +1133,16 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, _("standard input"));
- if (failed_opens)
- exit (EXIT_FAILURE);
- exit (EXIT_SUCCESS);
+ return failed_opens ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+/* Parse numeric arguments, ensuring MIN <= number <= INT_MAX. */
+
+static void
+getoptnum (const char *n_str, int min, int *num, const char *err)
+{
+ intmax_t tnum = xdectoimax (n_str, min, INT_MAX, "", err, 0);
+ *num = tnum;
}
/* Parse options of the form -scNNN.
@@ -1190,9 +1160,9 @@ getoptarg (char *arg, char switch_char, char *character, int *number)
{
long int tmp_long;
if (xstrtol (arg, NULL, 10, &tmp_long, "") != LONGINT_OK
- || tmp_long <= 0 || tmp_long > INT_MAX)
+ || tmp_long <= 0 || INT_MAX < tmp_long)
{
- error (0, 0,
+ error (0, INT_MAX < tmp_long ? EOVERFLOW : errno,
_("'-%c' extra characters or invalid number in the argument: %s"),
switch_char, quote (arg));
usage (EXIT_FAILURE);
@@ -1817,7 +1787,7 @@ print_page (void)
--p->lines_to_print;
if (p->lines_to_print <= 0)
{
- if (cols_ready_to_print () <= 0)
+ if (cols_ready_to_print () == 0)
break;
}
@@ -1851,7 +1821,7 @@ print_page (void)
--lines_left_on_page;
}
- if (cols_ready_to_print () <= 0 && !extremities)
+ if (cols_ready_to_print () == 0 && !extremities)
break;
if (double_space && pv)
@@ -2082,9 +2052,9 @@ pad_across_to (int position)
Otherwise, use newlines. */
static void
-pad_down (int lines)
+pad_down (unsigned int lines)
{
- int i;
+ unsigned int i;
if (use_form_feed)
putchar ('\f');
@@ -2758,6 +2728,7 @@ Usage: %s [OPTION]... [FILE]...\n\
Paginate or columnate FILE(s) for printing.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -2798,7 +2769,10 @@ Paginate or columnate FILE(s) for printing.\n\
fputs (_("\
-l, --length=PAGE_LENGTH\n\
set the page length to PAGE_LENGTH (66) lines\n\
- (default number of lines of text 56, and with -F 63)\n\
+ (default number of lines of text 56, and with -F 63).\n\
+ implies -t if PAGE_LENGTH <= 10\n\
+"), stdout);
+ fputs (_("\
-m, --merge print all files in parallel, one in each column,\n\
truncate lines, but join lines of full length with -J\n\
"), stdout);
@@ -2830,7 +2804,10 @@ Paginate or columnate FILE(s) for printing.\n\
separate columns by STRING,\n\
without -S: Default separator <TAB> with -J and <space>\n\
otherwise (same as -S\" \"), no effect on column options\n\
- -t, --omit-header omit page headers and trailers\n\
+"), stdout);
+ fputs (_("\
+ -t, --omit-header omit page headers and trailers;\n\
+ implied if PAGE_LENGTH <= 10\n\
"), stdout);
fputs (_("\
-T, --omit-pagination\n\
@@ -2850,12 +2827,7 @@ Paginate or columnate FILE(s) for printing.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
--t is implied if PAGE_LENGTH <= 10. With no FILE, or when FILE is -, read\n\
-standard input.\n\
-"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
diff --git a/src/printenv.c b/src/printenv.c
index e1faeb5f..6e8dbe6a 100644
--- a/src/printenv.c
+++ b/src/printenv.c
@@ -1,5 +1,5 @@
/* printenv -- print all or part of environment
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -72,7 +72,7 @@ If no VARIABLE is specified, print name and value pairs for them all.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -150,5 +150,5 @@ main (int argc, char **argv)
ok = (matches == argc - optind);
}
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/printf.c b/src/printf.c
index 7d523100..4260519d 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -1,5 +1,5 @@
/* printf - format and print data
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -129,7 +129,7 @@ and all C format specifications ending with one of diouxXfeEgGcs, with\n\
ARGUMENTs converted to proper type first. Variable widths are handled.\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -657,7 +657,7 @@ main (int argc, char **argv)
{
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
(char *) NULL);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
}
@@ -692,5 +692,5 @@ main (int argc, char **argv)
_("warning: ignoring excess arguments, starting with %s"),
quote (argv[0]));
- exit (exit_status);
+ return exit_status;
}
diff --git a/src/prog-fprintf.c b/src/prog-fprintf.c
index 4d3b449f..e7a96069 100644
--- a/src/prog-fprintf.c
+++ b/src/prog-fprintf.c
@@ -1,5 +1,5 @@
/* prog-fprintf.c - common formating output functions and definitions
- Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/prog-fprintf.h b/src/prog-fprintf.h
index 93df75a7..c639cd45 100644
--- a/src/prog-fprintf.h
+++ b/src/prog-fprintf.h
@@ -1,5 +1,5 @@
/* prog-fprintf.h - common formating output functions and definitions
- Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/ptx.c b/src/ptx.c
index d165e966..3aea4cdf 100644
--- a/src/ptx.c
+++ b/src/ptx.c
@@ -1,5 +1,5 @@
/* Permuted index for GNU, with keywords in their context.
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
François Pinard <pinard@iro.umontreal.ca>, 1988.
This program is free software: you can redistribute it and/or modify
@@ -631,9 +631,9 @@ sort_found_occurs (void)
{
/* Only one language for the time being. */
-
- qsort (occurs_table[0], number_of_occurs[0], sizeof **occurs_table,
- compare_occurs);
+ if (number_of_occurs[0])
+ qsort (occurs_table[0], number_of_occurs[0], sizeof **occurs_table,
+ compare_occurs);
}
/* Parameter files reading routines. */
@@ -1825,12 +1825,16 @@ Usage: %s [OPTION]... [INPUT]... (without -G)\n\
Output a permuted index, including context, of the words in the input files.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
-A, --auto-reference output automatically generated references\n\
-G, --traditional behave more like System V 'ptx'\n\
- -F, --flag-truncation=STRING use STRING for flagging line truncations\n\
+"), stdout);
+ fputs (_("\
+ -F, --flag-truncation=STRING use STRING for flagging line truncations.\n\
+ The default is '/'\n\
"), stdout);
fputs (_("\
-M, --macro-name=STRING macro name to use instead of 'xx'\n\
@@ -1854,11 +1858,7 @@ Output a permuted index, including context, of the words in the input files.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
-With no FILE, or when FILE is -, read standard input. Default is '-F /'.\n\
-"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -2155,5 +2155,5 @@ main (int argc, char **argv)
/* All done. */
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/pwd.c b/src/pwd.c
index d126ed75..9b9ddeb2 100644
--- a/src/pwd.c
+++ b/src/pwd.c
@@ -1,5 +1,5 @@
/* pwd - print current directory
- Copyright (C) 1994-2014 Free Software Foundation, Inc.
+ Copyright (C) 1994-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -68,7 +68,7 @@ Print the full filename of the current working directory.\n\
If no option is specified, -P is assumed.\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -372,7 +372,7 @@ main (int argc, char **argv)
if (wd)
{
puts (wd);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
}
@@ -390,5 +390,5 @@ main (int argc, char **argv)
file_name_free (file_name);
}
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/readlink.c b/src/readlink.c
index f46d948e..1778f639 100644
--- a/src/readlink.c
+++ b/src/readlink.c
@@ -1,5 +1,5 @@
/* readlink -- display value of a symbolic link.
- Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ Copyright (C) 2002-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -85,7 +85,7 @@ usage (int status)
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -174,5 +174,5 @@ main (int argc, char **argv)
}
}
- exit (status);
+ return status;
}
diff --git a/src/realpath.c b/src/realpath.c
index 0c553271..d1fca7b3 100644
--- a/src/realpath.c
+++ b/src/realpath.c
@@ -1,5 +1,5 @@
/* realpath - print the resolved path
- Copyright (C) 2011-2014 Free Software Foundation, Inc.
+ Copyright (C) 2011-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -88,7 +88,7 @@ all but the last component must exist\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -273,5 +273,5 @@ main (int argc, char **argv)
for (; optind < argc; ++optind)
ok &= process_path (argv[optind], can_mode);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/relpath.c b/src/relpath.c
index 29472e57..5ba4b9c1 100644
--- a/src/relpath.c
+++ b/src/relpath.c
@@ -1,5 +1,5 @@
/* relpath - print the relative path
- Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Copyright (C) 2012-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/relpath.h b/src/relpath.h
index 9017653a..759a8578 100644
--- a/src/relpath.h
+++ b/src/relpath.h
@@ -1,5 +1,5 @@
/* relpath - print the relative path
- Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Copyright (C) 2012-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/remove.c b/src/remove.c
index 4cc4a081..db8f993e 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -1,5 +1,5 @@
/* remove.c -- core functions for removing files and directories
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/remove.h b/src/remove.h
index 2563553d..a4501920 100644
--- a/src/remove.h
+++ b/src/remove.h
@@ -1,6 +1,6 @@
/* Remove directory entries.
- Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ Copyright (C) 1998-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/rm.c b/src/rm.c
index 5baea153..c1a23d5f 100644
--- a/src/rm.c
+++ b/src/rm.c
@@ -1,5 +1,5 @@
/* 'rm' file deletion utility for GNU.
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -132,7 +132,7 @@ usage (int status)
emit_try_help ();
else
{
- printf (_("Usage: %s [OPTION]... FILE...\n"), program_name);
+ printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
fputs (_("\
Remove (unlink) the FILE(s).\n\
\n\
@@ -180,7 +180,7 @@ Note that if you use rm to remove a file, it might be possible to recover\n\
some of its contents, given sufficient expertise and/or time. For greater\n\
assurance that the contents are truly unrecoverable, consider using shred.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -315,7 +315,7 @@ main (int argc, char **argv)
if (argc <= optind)
{
if (x.ignore_missing_files)
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
else
{
error (0, 0, _("missing operand"));
@@ -332,25 +332,25 @@ main (int argc, char **argv)
quote ("/"));
}
- size_t n_files = argc - optind;
+ uintmax_t n_files = argc - optind;
char **file = argv + optind;
if (prompt_once && (x.recursive || 3 < n_files))
{
fprintf (stderr,
(x.recursive
- ? ngettext ("%s: remove %zu argument recursively? ",
- "%s: remove %zu arguments recursively? ",
+ ? ngettext ("%s: remove %"PRIuMAX" argument recursively? ",
+ "%s: remove %"PRIuMAX" arguments recursively? ",
select_plural (n_files))
- : ngettext ("%s: remove %zu argument? ",
- "%s: remove %zu arguments? ",
+ : ngettext ("%s: remove %"PRIuMAX" argument? ",
+ "%s: remove %"PRIuMAX" arguments? ",
select_plural (n_files))),
program_name, n_files);
if (!yesno ())
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
enum RM_status status = rm (file, &x);
assert (VALID_STATUS (status));
- exit (status == RM_ERROR ? EXIT_FAILURE : EXIT_SUCCESS);
+ return status == RM_ERROR ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/rmdir.c b/src/rmdir.c
index e67d3b00..457e855e 100644
--- a/src/rmdir.c
+++ b/src/rmdir.c
@@ -1,6 +1,6 @@
/* rmdir -- remove directories
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -177,7 +177,7 @@ Remove the DIRECTORY(ies), if they are empty.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -248,5 +248,5 @@ main (int argc, char **argv)
}
}
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/runcon.c b/src/runcon.c
index 14ccc3d5..5b9cb334 100644
--- a/src/runcon.c
+++ b/src/runcon.c
@@ -1,5 +1,5 @@
/* runcon -- run command with specified security context
- Copyright (C) 2005-2014 Free Software Foundation, Inc.
+ Copyright (C) 2005-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -102,7 +102,7 @@ With neither CONTEXT nor COMMAND, print the current security context.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -177,7 +177,7 @@ main (int argc, char **argv)
error (EXIT_FAILURE, errno, _("failed to get current context"));
fputs (cur_context, stdout);
fputc ('\n', stdout);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
if (!(user || role || type || range || compute_trans))
@@ -258,9 +258,7 @@ main (int argc, char **argv)
execvp (argv[optind], argv + optind);
- {
- int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
- error (0, errno, "%s", argv[optind]);
- exit (exit_status);
- }
+ int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
+ error (0, errno, "%s", argv[optind]);
+ return exit_status;
}
diff --git a/src/selinux.c b/src/selinux.c
index ae454f8a..99b1fb0b 100644
--- a/src/selinux.c
+++ b/src/selinux.c
@@ -1,5 +1,5 @@
/* selinux - core functions for maintaining SELinux labeling
- Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Copyright (C) 2012-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/selinux.h b/src/selinux.h
index 8afaa495..f9b32768 100644
--- a/src/selinux.h
+++ b/src/selinux.h
@@ -1,5 +1,5 @@
/* selinux - core functions for maintaining SELinux labeling
- Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Copyright (C) 2012-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/seq.c b/src/seq.c
index 1124358c..2426c4de 100644
--- a/src/seq.c
+++ b/src/seq.c
@@ -1,5 +1,5 @@
/* seq - print sequence of numbers to standard output.
- Copyright (C) 1994-2014 Free Software Foundation, Inc.
+ Copyright (C) 1994-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -98,7 +98,7 @@ FORMAT must be suitable for printing one argument of type 'double';\n\
it defaults to %.PRECf if FIRST, INCREMENT, and LAST are all fixed point\n\
decimal numbers with maximum precision PREC, and to %g otherwise.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -147,17 +147,24 @@ scan_arg (const char *arg)
while (isspace (to_uchar (*arg)) || *arg == '+')
arg++;
- ret.width = strlen (arg);
+ /* Default to auto width and precision. */
+ ret.width = 0;
ret.precision = INT_MAX;
+ /* Use no precision (and possibly fast generation) for integers. */
+ char const *decimal_point = strchr (arg, '.');
+ if (! decimal_point && ! strchr (arg, 'p') /* not a hex float */)
+ ret.precision = 0;
+
+ /* auto set width and precision for decimal inputs. */
if (! arg[strcspn (arg, "xX")] && isfinite (ret.value))
{
- char const *decimal_point = strchr (arg, '.');
- if (! decimal_point)
- ret.precision = 0;
- else
+ size_t fraction_len = 0;
+ ret.width = strlen (arg);
+
+ if (decimal_point)
{
- size_t fraction_len = strcspn (decimal_point + 1, "eE");
+ fraction_len = strcspn (decimal_point + 1, "eE");
if (fraction_len <= INT_MAX)
ret.precision = fraction_len;
ret.width += (fraction_len == 0 /* #. -> # */
@@ -171,7 +178,8 @@ scan_arg (const char *arg)
if (e)
{
long exponent = strtol (e + 1, NULL, 10);
- ret.precision += exponent < 0 ? -exponent : 0;
+ ret.precision += exponent < 0 ? -exponent
+ : - MIN (ret.precision, exponent);
/* Don't account for e.... in the width since this is not output. */
ret.width -= strlen (arg) - (e - arg);
/* Adjust the width as per the exponent. */
@@ -186,6 +194,12 @@ scan_arg (const char *arg)
ret.width++;
exponent = -exponent;
}
+ else
+ {
+ if (decimal_point && ret.precision == 0 && fraction_len)
+ ret.width--; /* discount space for '.' */
+ exponent -= MIN (fraction_len, exponent);
+ }
ret.width += exponent;
}
}
@@ -411,52 +425,84 @@ trim_leading_zeros (char const *s)
static bool
seq_fast (char const *a, char const *b)
{
+ bool inf = STREQ (b, "inf");
+
/* Skip past any leading 0's. Without this, our naive cmp
function would declare 000 to be larger than 99. */
a = trim_leading_zeros (a);
b = trim_leading_zeros (b);
size_t p_len = strlen (a);
- size_t q_len = strlen (b);
- size_t n = MAX (p_len, q_len);
- char *p0 = xmalloc (n + 1);
- char *p = memcpy (p0 + n - p_len, a, p_len + 1);
- char *q0 = xmalloc (n + 1);
- char *q = memcpy (q0 + n - q_len, b, q_len + 1);
-
- bool ok = cmp (p, p_len, q, q_len) <= 0;
+ size_t q_len = inf ? 0 : strlen (b);
+
+ /* Allow for at least 31 digits without realloc.
+ 1 more than p_len is needed for the inf case. */
+ size_t inc_size = MAX (MAX (p_len + 1, q_len), 31);
+
+ /* Copy input strings (incl NUL) to end of new buffers. */
+ char *p0 = xmalloc (inc_size + 1);
+ char *p = memcpy (p0 + inc_size - p_len, a, p_len + 1);
+ char *q;
+ char *q0;
+ if (! inf)
+ {
+ q0 = xmalloc (inc_size + 1);
+ q = memcpy (q0 + inc_size - q_len, b, q_len + 1);
+ }
+ else
+ q = q0 = NULL;
+
+ bool ok = inf || cmp (p, p_len, q, q_len) <= 0;
if (ok)
{
- /* Buffer at least this many numbers per fwrite call.
- This gives a speed-up of more than 2x over the unbuffered code
+ /* Reduce number of fwrite calls which is seen to
+ give a speed-up of more than 2x over the unbuffered code
when printing the first 10^9 integers. */
- enum {N = 40};
- char *buf = xmalloc (N * (n + 1));
- char const *buf_end = buf + N * (n + 1);
+ size_t buf_size = MAX (BUFSIZ, (inc_size + 1) * 2);
+ char *buf = xmalloc (buf_size);
+ char const *buf_end = buf + buf_size;
- char *z = buf;
+ char *bufp = buf;
/* Write first number to buffer. */
- z = mempcpy (z, p, p_len);
+ bufp = mempcpy (bufp, p, p_len);
/* Append separator then number. */
- while (cmp (p, p_len, q, q_len) < 0)
+ while (inf || cmp (p, p_len, q, q_len) < 0)
{
- *z++ = *separator;
+ *bufp++ = *separator;
incr (&p, &p_len);
- z = mempcpy (z, p, p_len);
+
+ /* Double up the buffers when needed for the inf case. */
+ if (p_len == inc_size)
+ {
+ inc_size *= 2;
+ p0 = xrealloc (p0, inc_size + 1);
+ p = memmove (p0 + p_len, p0, p_len + 1);
+
+ if (buf_size < (inc_size + 1) * 2)
+ {
+ size_t buf_offset = bufp - buf;
+ buf_size = (inc_size + 1) * 2;
+ buf = xrealloc (buf, buf_size);
+ buf_end = buf + buf_size;
+ bufp = buf + buf_offset;
+ }
+ }
+
+ bufp = mempcpy (bufp, p, p_len);
/* If no place for another separator + number then
output buffer so far, and reset to start of buffer. */
- if (buf_end - (n + 1) < z)
+ if (buf_end - (p_len + 1) < bufp)
{
- fwrite (buf, z - buf, 1, stdout);
- z = buf;
+ fwrite (buf, bufp - buf, 1, stdout);
+ bufp = buf;
}
}
/* Write any remaining buffered output, and the terminator. */
- *z++ = *terminator;
- fwrite (buf, z - buf, 1, stdout);
+ *bufp++ = *terminator;
+ fwrite (buf, bufp - buf, 1, stdout);
IF_LINT (free (buf));
}
@@ -574,7 +620,7 @@ main (int argc, char **argv)
char const *s1 = n_args == 1 ? "1" : argv[optind];
char const *s2 = argv[optind + (n_args - 1)];
if (seq_fast (s1, s2))
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
/* Upon any failure, let the more general code deal with it. */
}
@@ -593,7 +639,8 @@ main (int argc, char **argv)
}
}
- if (first.precision == 0 && step.precision == 0 && last.precision == 0
+ if ((isfinite (first.value) && first.precision == 0)
+ && step.precision == 0 && last.precision == 0
&& 0 <= first.value && step.value == 1 && 0 <= last.value
&& !equal_width && !format_str && strlen (separator) == 1)
{
@@ -601,14 +648,16 @@ main (int argc, char **argv)
char *s2;
if (asprintf (&s1, "%0.Lf", first.value) < 0)
xalloc_die ();
- if (asprintf (&s2, "%0.Lf", last.value) < 0)
+ if (! isfinite (last.value))
+ s2 = xstrdup ("inf"); /* Ensure "inf" is used. */
+ else if (asprintf (&s2, "%0.Lf", last.value) < 0)
xalloc_die ();
if (*s1 != '-' && *s2 != '-' && seq_fast (s1, s2))
{
IF_LINT (free (s1));
IF_LINT (free (s2));
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
free (s1);
@@ -621,5 +670,5 @@ main (int argc, char **argv)
print_numbers (format_str, layout, first.value, step.value, last.value);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/shred.c b/src/shred.c
index bd88e383..63bcd6fc 100644
--- a/src/shred.c
+++ b/src/shred.c
@@ -1,6 +1,6 @@
/* shred.c - overwrite files and devices to make it harder to recover data
- Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Copyright (C) 1999-2015 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 1999 Colin Plumb.
This program is free software: you can redistribute it and/or modify
@@ -86,7 +86,7 @@
#include "system.h"
#include "argmatch.h"
-#include "xstrtol.h"
+#include "xdectoint.h"
#include "error.h"
#include "fcntl--.h"
#include "human.h"
@@ -171,6 +171,10 @@ usage (int status)
Overwrite the specified FILE(s) repeatedly, in order to make it harder\n\
for even very expensive hardware probing to recover the data.\n\
"), stdout);
+ fputs (_("\
+\n\
+If FILE is -, shred standard output.\n\
+"), stdout);
emit_mandatory_arg_note ();
@@ -191,8 +195,6 @@ for even very expensive hardware probing to recover the data.\n\
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
\n\
-If FILE is -, shred standard output.\n\
-\n\
Delete FILE(s) if --remove (-u) is specified. The default is not to remove\n\
the files because it is common to operate on device files like /dev/hda,\n\
and those files usually should not be removed.\n\
@@ -243,7 +245,7 @@ In addition, file system backups and remote mirrors may contain copies\n\
of the file that cannot be removed, and that will allow a shredded file\n\
to be recovered later.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -517,7 +519,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep,
/* Retry without direct I/O since this may not be supported
at all on some (file) systems, or with the current size.
- I.E. a specified --size that is not aligned, or when
+ I.e., a specified --size that is not aligned, or when
dealing with slop at the end of a file with --exact. */
if (! try_without_directio && errno == EINVAL)
{
@@ -1228,16 +1230,10 @@ main (int argc, char **argv)
break;
case 'n':
- {
- uintmax_t tmp;
- if (xstrtoumax (optarg, NULL, 10, &tmp, NULL) != LONGINT_OK
- || MIN (ULONG_MAX, SIZE_MAX / sizeof (int)) <= tmp)
- {
- error (EXIT_FAILURE, 0, _("%s: invalid number of passes"),
- quotearg_colon (optarg));
- }
- flags.n_iterations = tmp;
- }
+ flags.n_iterations = xdectoumax (optarg, 0,
+ MIN (ULONG_MAX,
+ SIZE_MAX / sizeof (int)), "",
+ _("invalid number of passes"), 0);
break;
case RANDOM_SOURCE_OPTION:
@@ -1255,17 +1251,8 @@ main (int argc, char **argv)
break;
case 's':
- {
- uintmax_t tmp;
- if ((xstrtoumax (optarg, NULL, 0, &tmp, "cbBkKMGTPEZY0")
- != LONGINT_OK)
- || OFF_T_MAX < tmp)
- {
- error (EXIT_FAILURE, 0, _("%s: invalid file size"),
- quotearg_colon (optarg));
- }
- flags.size = tmp;
- }
+ flags.size = xnumtoumax (optarg, 0, 0, OFF_T_MAX, "cbBkKMGTPEZY0",
+ _("invalid file size"), 0);
break;
case 'v':
@@ -1318,7 +1305,7 @@ main (int argc, char **argv)
free (qname);
}
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
/*
* vim:sw=2:sts=2:
diff --git a/src/shuf.c b/src/shuf.c
index 2505be6f..ff2337d3 100644
--- a/src/shuf.c
+++ b/src/shuf.c
@@ -1,6 +1,6 @@
/* Shuffle lines of text.
- Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ Copyright (C) 2006-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@
#include "randperm.h"
#include "read-file.h"
#include "stdio--.h"
+#include "xdectoint.h"
#include "xstrtol.h"
/* The official name of this program (e.g., no 'g' prefix). */
@@ -68,6 +69,7 @@ Usage: %s [OPTION]... [FILE]\n\
Write a random permutation of the input lines to standard output.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -83,11 +85,7 @@ Write a random permutation of the input lines to standard output.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
-With no FILE, or when FILE is -, read standard input.\n\
-"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
@@ -272,7 +270,7 @@ read_input (FILE *in, char eolbyte, char ***pline)
size_t n_lines;
/* TODO: We should limit the amount of data read here,
- to less than RESERVOIR_MIN_INPUT. I.E. adjust fread_file() to support
+ to less than RESERVOIR_MIN_INPUT. I.e., adjust fread_file() to support
taking a byte limit. We'd then need to ensure we handle a line spanning
this boundary. With that in place we could set use_reservoir_sampling
when used==RESERVOIR_MIN_INPUT, and have read_input_reservoir_sampling()
@@ -422,7 +420,6 @@ main (int argc, char **argv)
case 'i':
{
- unsigned long int argval = 0;
char *p = strchr (optarg, '-');
char const *hi_optarg = optarg;
bool invalid = !p;
@@ -434,22 +431,19 @@ main (int argc, char **argv)
if (p)
{
*p = '\0';
- invalid = ((xstrtoul (optarg, NULL, 10, &argval, NULL)
- != LONGINT_OK)
- || SIZE_MAX < argval);
+ lo_input = xdectoumax (optarg, 0, SIZE_MAX, "",
+ _("invalid input range"), 0);
*p = '-';
- lo_input = argval;
hi_optarg = p + 1;
}
- invalid |= ((xstrtoul (hi_optarg, NULL, 10, &argval, NULL)
- != LONGINT_OK)
- || SIZE_MAX < argval);
- hi_input = argval;
+ hi_input = xdectoumax (hi_optarg, 0, SIZE_MAX, "",
+ _("invalid input range"), 0);
+
n_lines = hi_input - lo_input + 1;
invalid |= ((lo_input <= hi_input) == (n_lines == 0));
if (invalid)
- error (EXIT_FAILURE, 0, _("invalid input range %s"),
+ error (EXIT_FAILURE, errno, "%s: %s", _("invalid input range"),
quote (optarg));
}
break;
@@ -462,7 +456,7 @@ main (int argc, char **argv)
if (e == LONGINT_OK)
head_lines = MIN (head_lines, argval);
else if (e != LONGINT_OVERFLOW)
- error (EXIT_FAILURE, 0, _("invalid line count %s"),
+ error (EXIT_FAILURE, 0, _("invalid line count: %s"),
quote (optarg));
}
break;
@@ -504,7 +498,7 @@ main (int argc, char **argv)
}
if (input_range ? 0 < n_operands : !echo && 1 < n_operands)
{
- error (0, 0, _("extra operand %s"), quote (operand[1]));
+ error (0, 0, _("extra operand %s"), quote (operand[!input_range]));
usage (EXIT_FAILURE);
}
@@ -622,5 +616,5 @@ main (int argc, char **argv)
}
#endif
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/single-binary.mk b/src/single-binary.mk
index cc836d75..de3f299e 100644
--- a/src/single-binary.mk
+++ b/src/single-binary.mk
@@ -6,475 +6,475 @@ src_libsinglebin_arch_a_DEPENDENCIES = src/libsinglebin_uname.a
noinst_LIBRARIES += src/libsinglebin_arch.a
src_libsinglebin_arch_a_SOURCES = src/coreutils-arch.c
src_libsinglebin_arch_a_ldadd = src/libsinglebin_uname.a
-src_libsinglebin_arch_a_CFLAGS = "-Dmain=_single_binary_main_arch(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_arch" -Dusage=_usage_arch $(src_coreutils_CFLAGS)
+src_libsinglebin_arch_a_CFLAGS = "-Dmain=single_binary_main_arch (int, char **); int single_binary_main_arch" -Dusage=_usage_arch $(src_coreutils_CFLAGS)
# Command hostname
noinst_LIBRARIES += src/libsinglebin_hostname.a
src_libsinglebin_hostname_a_SOURCES = src/hostname.c
src_libsinglebin_hostname_a_ldadd = $(GETHOSTNAME_LIB)
-src_libsinglebin_hostname_a_CFLAGS = "-Dmain=_single_binary_main_hostname(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_hostname" -Dusage=_usage_hostname $(src_coreutils_CFLAGS)
+src_libsinglebin_hostname_a_CFLAGS = "-Dmain=single_binary_main_hostname (int, char **); int single_binary_main_hostname" -Dusage=_usage_hostname $(src_coreutils_CFLAGS)
# Command chroot
noinst_LIBRARIES += src/libsinglebin_chroot.a
src_libsinglebin_chroot_a_SOURCES = src/chroot.c
-src_libsinglebin_chroot_a_CFLAGS = "-Dmain=_single_binary_main_chroot(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_chroot" -Dusage=_usage_chroot $(src_coreutils_CFLAGS)
+src_libsinglebin_chroot_a_CFLAGS = "-Dmain=single_binary_main_chroot (int, char **); int single_binary_main_chroot" -Dusage=_usage_chroot $(src_coreutils_CFLAGS)
# Command df
noinst_LIBRARIES += src/libsinglebin_df.a
src_libsinglebin_df_a_SOURCES = src/df.c src/find-mount-point.c
src_libsinglebin_df_a_ldadd = $(LIBICONV)
-src_libsinglebin_df_a_CFLAGS = "-Dmain=_single_binary_main_df(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_df" -Dusage=_usage_df $(src_coreutils_CFLAGS)
+src_libsinglebin_df_a_CFLAGS = "-Dmain=single_binary_main_df (int, char **); int single_binary_main_df" -Dusage=_usage_df $(src_coreutils_CFLAGS)
# Command hostid
noinst_LIBRARIES += src/libsinglebin_hostid.a
src_libsinglebin_hostid_a_SOURCES = src/hostid.c
-src_libsinglebin_hostid_a_CFLAGS = "-Dmain=_single_binary_main_hostid(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_hostid" -Dusage=_usage_hostid $(src_coreutils_CFLAGS)
+src_libsinglebin_hostid_a_CFLAGS = "-Dmain=single_binary_main_hostid (int, char **); int single_binary_main_hostid" -Dusage=_usage_hostid $(src_coreutils_CFLAGS)
# Command nice
noinst_LIBRARIES += src/libsinglebin_nice.a
src_libsinglebin_nice_a_SOURCES = src/nice.c
-src_libsinglebin_nice_a_CFLAGS = "-Dmain=_single_binary_main_nice(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_nice" -Dusage=_usage_nice $(src_coreutils_CFLAGS)
+src_libsinglebin_nice_a_CFLAGS = "-Dmain=single_binary_main_nice (int, char **); int single_binary_main_nice" -Dusage=_usage_nice $(src_coreutils_CFLAGS)
# Command pinky
noinst_LIBRARIES += src/libsinglebin_pinky.a
src_libsinglebin_pinky_a_SOURCES = src/pinky.c
src_libsinglebin_pinky_a_ldadd = $(GETADDRINFO_LIB)
-src_libsinglebin_pinky_a_CFLAGS = "-Dmain=_single_binary_main_pinky(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_pinky" -Dusage=_usage_pinky $(src_coreutils_CFLAGS)
+src_libsinglebin_pinky_a_CFLAGS = "-Dmain=single_binary_main_pinky (int, char **); int single_binary_main_pinky" -Dusage=_usage_pinky $(src_coreutils_CFLAGS)
# Command stdbuf
noinst_LIBRARIES += src/libsinglebin_stdbuf.a
src_libsinglebin_stdbuf_a_SOURCES = src/stdbuf.c
src_libsinglebin_stdbuf_a_ldadd = $(LIBICONV)
-src_libsinglebin_stdbuf_a_CFLAGS = "-Dmain=_single_binary_main_stdbuf(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_stdbuf" -Dusage=_usage_stdbuf $(src_coreutils_CFLAGS)
+src_libsinglebin_stdbuf_a_CFLAGS = "-Dmain=single_binary_main_stdbuf (int, char **); int single_binary_main_stdbuf" -Dusage=_usage_stdbuf $(src_coreutils_CFLAGS)
# Command stty
noinst_LIBRARIES += src/libsinglebin_stty.a
src_libsinglebin_stty_a_SOURCES = src/stty.c
-src_libsinglebin_stty_a_CFLAGS = "-Dmain=_single_binary_main_stty(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_stty" -Dusage=_usage_stty $(src_coreutils_CFLAGS)
+src_libsinglebin_stty_a_CFLAGS = "-Dmain=single_binary_main_stty (int, char **); int single_binary_main_stty" -Dusage=_usage_stty $(src_coreutils_CFLAGS)
# Command uptime
noinst_LIBRARIES += src/libsinglebin_uptime.a
src_libsinglebin_uptime_a_SOURCES = src/uptime.c
src_libsinglebin_uptime_a_ldadd = $(GETLOADAVG_LIBS)
-src_libsinglebin_uptime_a_CFLAGS = "-Dmain=_single_binary_main_uptime(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_uptime" -Dusage=_usage_uptime $(src_coreutils_CFLAGS)
+src_libsinglebin_uptime_a_CFLAGS = "-Dmain=single_binary_main_uptime (int, char **); int single_binary_main_uptime" -Dusage=_usage_uptime $(src_coreutils_CFLAGS)
# Command users
noinst_LIBRARIES += src/libsinglebin_users.a
src_libsinglebin_users_a_SOURCES = src/users.c
-src_libsinglebin_users_a_CFLAGS = "-Dmain=_single_binary_main_users(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_users" -Dusage=_usage_users $(src_coreutils_CFLAGS)
+src_libsinglebin_users_a_CFLAGS = "-Dmain=single_binary_main_users (int, char **); int single_binary_main_users" -Dusage=_usage_users $(src_coreutils_CFLAGS)
# Command who
noinst_LIBRARIES += src/libsinglebin_who.a
src_libsinglebin_who_a_SOURCES = src/who.c
src_libsinglebin_who_a_ldadd = $(GETADDRINFO_LIB)
-src_libsinglebin_who_a_CFLAGS = "-Dmain=_single_binary_main_who(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_who" -Dusage=_usage_who $(src_coreutils_CFLAGS)
+src_libsinglebin_who_a_CFLAGS = "-Dmain=single_binary_main_who (int, char **); int single_binary_main_who" -Dusage=_usage_who $(src_coreutils_CFLAGS)
# Command _
noinst_LIBRARIES += src/libsinglebin__.a
src_libsinglebin___a_SOURCES = src/lbracket.c
src_libsinglebin___a_ldadd = $(src_test_LDADD)
-src_libsinglebin___a_CFLAGS = "-Dmain=_single_binary_main__(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main__" -Dusage=_usage__ $(src_coreutils_CFLAGS)
+src_libsinglebin___a_CFLAGS = "-Dmain=single_binary_main__ (int, char **); int single_binary_main__" -Dusage=_usage__ $(src_coreutils_CFLAGS)
# Command base64
noinst_LIBRARIES += src/libsinglebin_base64.a
src_libsinglebin_base64_a_SOURCES = src/base64.c
-src_libsinglebin_base64_a_CFLAGS = "-Dmain=_single_binary_main_base64(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_base64" -Dusage=_usage_base64 $(src_coreutils_CFLAGS)
+src_libsinglebin_base64_a_CFLAGS = "-Dmain=single_binary_main_base64 (int, char **); int single_binary_main_base64" -Dusage=_usage_base64 $(src_coreutils_CFLAGS)
# Command basename
noinst_LIBRARIES += src/libsinglebin_basename.a
src_libsinglebin_basename_a_SOURCES = src/basename.c
-src_libsinglebin_basename_a_CFLAGS = "-Dmain=_single_binary_main_basename(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_basename" -Dusage=_usage_basename $(src_coreutils_CFLAGS)
+src_libsinglebin_basename_a_CFLAGS = "-Dmain=single_binary_main_basename (int, char **); int single_binary_main_basename" -Dusage=_usage_basename $(src_coreutils_CFLAGS)
# Command cat
noinst_LIBRARIES += src/libsinglebin_cat.a
src_libsinglebin_cat_a_SOURCES = src/cat.c
src_libsinglebin_cat_a_ldadd = $(LIBICONV)
-src_libsinglebin_cat_a_CFLAGS = "-Dmain=_single_binary_main_cat(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_cat" -Dusage=_usage_cat $(src_coreutils_CFLAGS)
+src_libsinglebin_cat_a_CFLAGS = "-Dmain=single_binary_main_cat (int, char **); int single_binary_main_cat" -Dusage=_usage_cat $(src_coreutils_CFLAGS)
# Command chcon
noinst_LIBRARIES += src/libsinglebin_chcon.a
src_libsinglebin_chcon_a_SOURCES = src/chcon.c
src_libsinglebin_chcon_a_ldadd = $(LIB_SELINUX)
-src_libsinglebin_chcon_a_CFLAGS = "-Dmain=_single_binary_main_chcon(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_chcon" -Dusage=_usage_chcon $(src_coreutils_CFLAGS)
+src_libsinglebin_chcon_a_CFLAGS = "-Dmain=single_binary_main_chcon (int, char **); int single_binary_main_chcon" -Dusage=_usage_chcon $(src_coreutils_CFLAGS)
# Command chgrp
noinst_LIBRARIES += src/libsinglebin_chgrp.a
src_libsinglebin_chgrp_a_SOURCES = src/chgrp.c src/chown-core.c
-src_libsinglebin_chgrp_a_CFLAGS = "-Dmain=_single_binary_main_chgrp(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_chgrp" -Dusage=_usage_chgrp $(src_coreutils_CFLAGS)
+src_libsinglebin_chgrp_a_CFLAGS = "-Dmain=single_binary_main_chgrp (int, char **); int single_binary_main_chgrp" -Dusage=_usage_chgrp $(src_coreutils_CFLAGS)
# Command chmod
noinst_LIBRARIES += src/libsinglebin_chmod.a
src_libsinglebin_chmod_a_SOURCES = src/chmod.c
-src_libsinglebin_chmod_a_CFLAGS = "-Dmain=_single_binary_main_chmod(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_chmod" -Dusage=_usage_chmod $(src_coreutils_CFLAGS)
+src_libsinglebin_chmod_a_CFLAGS = "-Dmain=single_binary_main_chmod (int, char **); int single_binary_main_chmod" -Dusage=_usage_chmod $(src_coreutils_CFLAGS)
# Command chown
noinst_LIBRARIES += src/libsinglebin_chown.a
src_libsinglebin_chown_a_SOURCES = src/chown.c src/chown-core.c
-src_libsinglebin_chown_a_CFLAGS = "-Dmain=_single_binary_main_chown(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_chown" -Dusage=_usage_chown $(src_coreutils_CFLAGS)
+src_libsinglebin_chown_a_CFLAGS = "-Dmain=single_binary_main_chown (int, char **); int single_binary_main_chown" -Dusage=_usage_chown $(src_coreutils_CFLAGS)
# Command cksum
noinst_LIBRARIES += src/libsinglebin_cksum.a
src_libsinglebin_cksum_a_SOURCES = src/cksum.c
-src_libsinglebin_cksum_a_CFLAGS = "-Dmain=_single_binary_main_cksum(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_cksum" -Dusage=_usage_cksum $(src_coreutils_CFLAGS)
+src_libsinglebin_cksum_a_CFLAGS = "-Dmain=single_binary_main_cksum (int, char **); int single_binary_main_cksum" -Dusage=_usage_cksum $(src_coreutils_CFLAGS)
# Command comm
noinst_LIBRARIES += src/libsinglebin_comm.a
src_libsinglebin_comm_a_SOURCES = src/comm.c
-src_libsinglebin_comm_a_CFLAGS = "-Dmain=_single_binary_main_comm(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_comm" -Dusage=_usage_comm $(src_coreutils_CFLAGS)
+src_libsinglebin_comm_a_CFLAGS = "-Dmain=single_binary_main_comm (int, char **); int single_binary_main_comm" -Dusage=_usage_comm $(src_coreutils_CFLAGS)
# Command cp
noinst_LIBRARIES += src/libsinglebin_cp.a
src_libsinglebin_cp_a_SOURCES = src/cp.c $(copy_sources) $(selinux_sources)
src_libsinglebin_cp_a_ldadd = $(copy_ldadd) $(LIBICONV)
-src_libsinglebin_cp_a_CFLAGS = "-Dmain=_single_binary_main_cp(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_cp" -Dusage=_usage_cp $(src_coreutils_CFLAGS)
+src_libsinglebin_cp_a_CFLAGS = "-Dmain=single_binary_main_cp (int, char **); int single_binary_main_cp" -Dusage=_usage_cp $(src_coreutils_CFLAGS)
# Command csplit
noinst_LIBRARIES += src/libsinglebin_csplit.a
src_libsinglebin_csplit_a_SOURCES = src/csplit.c
-src_libsinglebin_csplit_a_CFLAGS = "-Dmain=_single_binary_main_csplit(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_csplit" -Dusage=_usage_csplit $(src_coreutils_CFLAGS)
+src_libsinglebin_csplit_a_CFLAGS = "-Dmain=single_binary_main_csplit (int, char **); int single_binary_main_csplit" -Dusage=_usage_csplit $(src_coreutils_CFLAGS)
# Command cut
noinst_LIBRARIES += src/libsinglebin_cut.a
src_libsinglebin_cut_a_SOURCES = src/cut.c
-src_libsinglebin_cut_a_CFLAGS = "-Dmain=_single_binary_main_cut(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_cut" -Dusage=_usage_cut $(src_coreutils_CFLAGS)
+src_libsinglebin_cut_a_CFLAGS = "-Dmain=single_binary_main_cut (int, char **); int single_binary_main_cut" -Dusage=_usage_cut $(src_coreutils_CFLAGS)
# Command date
noinst_LIBRARIES += src/libsinglebin_date.a
src_libsinglebin_date_a_SOURCES = src/date.c
src_libsinglebin_date_a_ldadd = $(LIB_CLOCK_GETTIME)
-src_libsinglebin_date_a_CFLAGS = "-Dmain=_single_binary_main_date(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_date" -Dusage=_usage_date $(src_coreutils_CFLAGS)
+src_libsinglebin_date_a_CFLAGS = "-Dmain=single_binary_main_date (int, char **); int single_binary_main_date" -Dusage=_usage_date $(src_coreutils_CFLAGS)
# Command dd
noinst_LIBRARIES += src/libsinglebin_dd.a
src_libsinglebin_dd_a_SOURCES = src/dd.c
src_libsinglebin_dd_a_ldadd = $(LIB_GETHRXTIME) $(LIB_FDATASYNC)
-src_libsinglebin_dd_a_CFLAGS = "-Dmain=_single_binary_main_dd(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_dd" -Dusage=_usage_dd $(src_coreutils_CFLAGS)
+src_libsinglebin_dd_a_CFLAGS = "-Dmain=single_binary_main_dd (int, char **); int single_binary_main_dd" -Dusage=_usage_dd $(src_coreutils_CFLAGS)
# Command dir
noinst_LIBRARIES += src/libsinglebin_dir.a
src_libsinglebin_dir_a_SOURCES = src/coreutils-dir.c
src_libsinglebin_dir_a_ldadd = $(src_ls_LDADD) src/libsinglebin_ls.a
-src_libsinglebin_dir_a_CFLAGS = "-Dmain=_single_binary_main_dir(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_dir" -Dusage=_usage_dir $(src_coreutils_CFLAGS)
+src_libsinglebin_dir_a_CFLAGS = "-Dmain=single_binary_main_dir (int, char **); int single_binary_main_dir" -Dusage=_usage_dir $(src_coreutils_CFLAGS)
# Command dircolors
noinst_LIBRARIES += src/libsinglebin_dircolors.a
src_libsinglebin_dircolors_a_SOURCES = src/dircolors.c
-src_libsinglebin_dircolors_a_CFLAGS = "-Dmain=_single_binary_main_dircolors(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_dircolors" -Dusage=_usage_dircolors $(src_coreutils_CFLAGS)
+src_libsinglebin_dircolors_a_CFLAGS = "-Dmain=single_binary_main_dircolors (int, char **); int single_binary_main_dircolors" -Dusage=_usage_dircolors $(src_coreutils_CFLAGS)
# Command dirname
noinst_LIBRARIES += src/libsinglebin_dirname.a
src_libsinglebin_dirname_a_SOURCES = src/dirname.c
-src_libsinglebin_dirname_a_CFLAGS = "-Dmain=_single_binary_main_dirname(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_dirname" -Dusage=_usage_dirname $(src_coreutils_CFLAGS)
+src_libsinglebin_dirname_a_CFLAGS = "-Dmain=single_binary_main_dirname (int, char **); int single_binary_main_dirname" -Dusage=_usage_dirname $(src_coreutils_CFLAGS)
# Command du
noinst_LIBRARIES += src/libsinglebin_du.a
src_libsinglebin_du_a_SOURCES = src/du.c
src_libsinglebin_du_a_ldadd = $(LIBICONV)
-src_libsinglebin_du_a_CFLAGS = "-Dmain=_single_binary_main_du(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_du" -Dusage=_usage_du $(src_coreutils_CFLAGS)
+src_libsinglebin_du_a_CFLAGS = "-Dmain=single_binary_main_du (int, char **); int single_binary_main_du" -Dusage=_usage_du $(src_coreutils_CFLAGS)
# Command echo
noinst_LIBRARIES += src/libsinglebin_echo.a
src_libsinglebin_echo_a_SOURCES = src/echo.c
-src_libsinglebin_echo_a_CFLAGS = "-Dmain=_single_binary_main_echo(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_echo" -Dusage=_usage_echo $(src_coreutils_CFLAGS)
+src_libsinglebin_echo_a_CFLAGS = "-Dmain=single_binary_main_echo (int, char **); int single_binary_main_echo" -Dusage=_usage_echo $(src_coreutils_CFLAGS)
# Command env
noinst_LIBRARIES += src/libsinglebin_env.a
src_libsinglebin_env_a_SOURCES = src/env.c
-src_libsinglebin_env_a_CFLAGS = "-Dmain=_single_binary_main_env(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_env" -Dusage=_usage_env $(src_coreutils_CFLAGS)
+src_libsinglebin_env_a_CFLAGS = "-Dmain=single_binary_main_env (int, char **); int single_binary_main_env" -Dusage=_usage_env $(src_coreutils_CFLAGS)
# Command expand
noinst_LIBRARIES += src/libsinglebin_expand.a
src_libsinglebin_expand_a_SOURCES = src/expand.c
-src_libsinglebin_expand_a_CFLAGS = "-Dmain=_single_binary_main_expand(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_expand" -Dusage=_usage_expand $(src_coreutils_CFLAGS)
+src_libsinglebin_expand_a_CFLAGS = "-Dmain=single_binary_main_expand (int, char **); int single_binary_main_expand" -Dusage=_usage_expand $(src_coreutils_CFLAGS)
# Command expr
noinst_LIBRARIES += src/libsinglebin_expr.a
src_libsinglebin_expr_a_SOURCES = src/expr.c
src_libsinglebin_expr_a_ldadd = $(LIB_GMP)
-src_libsinglebin_expr_a_CFLAGS = "-Dmain=_single_binary_main_expr(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_expr" -Dusage=_usage_expr $(src_coreutils_CFLAGS)
+src_libsinglebin_expr_a_CFLAGS = "-Dmain=single_binary_main_expr (int, char **); int single_binary_main_expr" -Dusage=_usage_expr $(src_coreutils_CFLAGS)
# Command factor
noinst_LIBRARIES += src/libsinglebin_factor.a
src_libsinglebin_factor_a_SOURCES = src/factor.c
src_libsinglebin_factor_a_ldadd = $(LIB_GMP) $(LIBICONV)
-src_libsinglebin_factor_a_CFLAGS = "-Dmain=_single_binary_main_factor(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_factor" -Dusage=_usage_factor $(src_coreutils_CFLAGS)
+src_libsinglebin_factor_a_CFLAGS = "-Dmain=single_binary_main_factor (int, char **); int single_binary_main_factor" -Dusage=_usage_factor $(src_coreutils_CFLAGS)
# Command false
noinst_LIBRARIES += src/libsinglebin_false.a
src_libsinglebin_false_a_SOURCES = src/false.c
-src_libsinglebin_false_a_CFLAGS = "-Dmain=_single_binary_main_false(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_false" -Dusage=_usage_false $(src_coreutils_CFLAGS)
+src_libsinglebin_false_a_CFLAGS = "-Dmain=single_binary_main_false (int, char **); int single_binary_main_false" -Dusage=_usage_false $(src_coreutils_CFLAGS)
# Command fmt
noinst_LIBRARIES += src/libsinglebin_fmt.a
src_libsinglebin_fmt_a_SOURCES = src/fmt.c
-src_libsinglebin_fmt_a_CFLAGS = "-Dmain=_single_binary_main_fmt(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_fmt" -Dusage=_usage_fmt $(src_coreutils_CFLAGS)
+src_libsinglebin_fmt_a_CFLAGS = "-Dmain=single_binary_main_fmt (int, char **); int single_binary_main_fmt" -Dusage=_usage_fmt $(src_coreutils_CFLAGS)
# Command fold
noinst_LIBRARIES += src/libsinglebin_fold.a
src_libsinglebin_fold_a_SOURCES = src/fold.c
-src_libsinglebin_fold_a_CFLAGS = "-Dmain=_single_binary_main_fold(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_fold" -Dusage=_usage_fold $(src_coreutils_CFLAGS)
+src_libsinglebin_fold_a_CFLAGS = "-Dmain=single_binary_main_fold (int, char **); int single_binary_main_fold" -Dusage=_usage_fold $(src_coreutils_CFLAGS)
# Command ginstall
noinst_LIBRARIES += src/libsinglebin_ginstall.a
src_libsinglebin_ginstall_a_SOURCES = src/install.c src/prog-fprintf.c $(copy_sources) $(selinux_sources)
src_libsinglebin_ginstall_a_ldadd = $(copy_ldadd) $(LIB_SELINUX) $(LIB_CLOCK_GETTIME)
-src_libsinglebin_ginstall_a_CFLAGS = "-Dmain=_single_binary_main_ginstall(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_ginstall" -Dusage=_usage_ginstall $(src_coreutils_CFLAGS)
+src_libsinglebin_ginstall_a_CFLAGS = "-Dmain=single_binary_main_ginstall (int, char **); int single_binary_main_ginstall" -Dusage=_usage_ginstall $(src_coreutils_CFLAGS)
src_libsinglebin_ginstall_a_CPPFLAGS = -DENABLE_MATCHPATHCON=1 $(AM_CPPFLAGS)
# Command groups
noinst_LIBRARIES += src/libsinglebin_groups.a
src_libsinglebin_groups_a_SOURCES = src/groups.c src/group-list.c
-src_libsinglebin_groups_a_CFLAGS = "-Dmain=_single_binary_main_groups(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_groups" -Dusage=_usage_groups $(src_coreutils_CFLAGS)
+src_libsinglebin_groups_a_CFLAGS = "-Dmain=single_binary_main_groups (int, char **); int single_binary_main_groups" -Dusage=_usage_groups $(src_coreutils_CFLAGS)
# Command head
noinst_LIBRARIES += src/libsinglebin_head.a
src_libsinglebin_head_a_SOURCES = src/head.c
-src_libsinglebin_head_a_CFLAGS = "-Dmain=_single_binary_main_head(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_head" -Dusage=_usage_head $(src_coreutils_CFLAGS)
+src_libsinglebin_head_a_CFLAGS = "-Dmain=single_binary_main_head (int, char **); int single_binary_main_head" -Dusage=_usage_head $(src_coreutils_CFLAGS)
# Command id
noinst_LIBRARIES += src/libsinglebin_id.a
src_libsinglebin_id_a_SOURCES = src/id.c src/group-list.c
src_libsinglebin_id_a_ldadd = $(LIB_SELINUX) $(LIB_SMACK)
-src_libsinglebin_id_a_CFLAGS = "-Dmain=_single_binary_main_id(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_id" -Dusage=_usage_id $(src_coreutils_CFLAGS)
+src_libsinglebin_id_a_CFLAGS = "-Dmain=single_binary_main_id (int, char **); int single_binary_main_id" -Dusage=_usage_id $(src_coreutils_CFLAGS)
# Command join
noinst_LIBRARIES += src/libsinglebin_join.a
src_libsinglebin_join_a_SOURCES = src/join.c
-src_libsinglebin_join_a_CFLAGS = "-Dmain=_single_binary_main_join(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_join" -Dusage=_usage_join $(src_coreutils_CFLAGS)
+src_libsinglebin_join_a_CFLAGS = "-Dmain=single_binary_main_join (int, char **); int single_binary_main_join" -Dusage=_usage_join $(src_coreutils_CFLAGS)
# Command kill
noinst_LIBRARIES += src/libsinglebin_kill.a
src_libsinglebin_kill_a_SOURCES = src/kill.c src/operand2sig.c
src_libsinglebin_kill_a_ldadd = $(LIBTHREAD)
-src_libsinglebin_kill_a_CFLAGS = "-Dmain=_single_binary_main_kill(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_kill" -Dusage=_usage_kill $(src_coreutils_CFLAGS)
+src_libsinglebin_kill_a_CFLAGS = "-Dmain=single_binary_main_kill (int, char **); int single_binary_main_kill" -Dusage=_usage_kill $(src_coreutils_CFLAGS)
# Command link
noinst_LIBRARIES += src/libsinglebin_link.a
src_libsinglebin_link_a_SOURCES = src/link.c
-src_libsinglebin_link_a_CFLAGS = "-Dmain=_single_binary_main_link(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_link" -Dusage=_usage_link $(src_coreutils_CFLAGS)
+src_libsinglebin_link_a_CFLAGS = "-Dmain=single_binary_main_link (int, char **); int single_binary_main_link" -Dusage=_usage_link $(src_coreutils_CFLAGS)
# Command ln
noinst_LIBRARIES += src/libsinglebin_ln.a
src_libsinglebin_ln_a_SOURCES = src/ln.c src/relpath.c src/relpath.h
-src_libsinglebin_ln_a_CFLAGS = "-Dmain=_single_binary_main_ln(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_ln" -Dusage=_usage_ln $(src_coreutils_CFLAGS)
+src_libsinglebin_ln_a_CFLAGS = "-Dmain=single_binary_main_ln (int, char **); int single_binary_main_ln" -Dusage=_usage_ln $(src_coreutils_CFLAGS)
# Command logname
noinst_LIBRARIES += src/libsinglebin_logname.a
src_libsinglebin_logname_a_SOURCES = src/logname.c
-src_libsinglebin_logname_a_CFLAGS = "-Dmain=_single_binary_main_logname(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_logname" -Dusage=_usage_logname $(src_coreutils_CFLAGS)
+src_libsinglebin_logname_a_CFLAGS = "-Dmain=single_binary_main_logname (int, char **); int single_binary_main_logname" -Dusage=_usage_logname $(src_coreutils_CFLAGS)
# Command ls
noinst_LIBRARIES += src/libsinglebin_ls.a
src_libsinglebin_ls_a_SOURCES = src/ls.c src/ls-ls.c
-src_libsinglebin_ls_a_ldadd = $(LIB_SELINUX) $(LIB_SMACK) $(LIB_CLOCK_GETTIME) $(LIB_CAP) $(LIB_ACL)
-src_libsinglebin_ls_a_CFLAGS = "-Dmain=_single_binary_main_ls(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_ls" -Dusage=_usage_ls $(src_coreutils_CFLAGS)
+src_libsinglebin_ls_a_ldadd = $(LIB_SELINUX) $(LIB_SMACK) $(LIB_CLOCK_GETTIME) $(LIB_CAP) $(LIB_HAS_ACL)
+src_libsinglebin_ls_a_CFLAGS = "-Dmain=single_binary_main_ls (int, char **); int single_binary_main_ls" -Dusage=_usage_ls $(src_coreutils_CFLAGS)
# Command md5sum
noinst_LIBRARIES += src/libsinglebin_md5sum.a
src_libsinglebin_md5sum_a_SOURCES = src/md5sum.c
src_libsinglebin_md5sum_a_ldadd = $(LIB_CRYPTO)
-src_libsinglebin_md5sum_a_CFLAGS = "-Dmain=_single_binary_main_md5sum(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_md5sum" -Dusage=_usage_md5sum $(src_coreutils_CFLAGS)
+src_libsinglebin_md5sum_a_CFLAGS = "-Dmain=single_binary_main_md5sum (int, char **); int single_binary_main_md5sum" -Dusage=_usage_md5sum $(src_coreutils_CFLAGS)
src_libsinglebin_md5sum_a_CPPFLAGS = -DHASH_ALGO_MD5=1 $(AM_CPPFLAGS)
# Command mkdir
noinst_LIBRARIES += src/libsinglebin_mkdir.a
src_libsinglebin_mkdir_a_SOURCES = src/mkdir.c src/prog-fprintf.c $(selinux_sources)
src_libsinglebin_mkdir_a_ldadd = $(LIB_SELINUX) $(LIB_SMACK)
-src_libsinglebin_mkdir_a_CFLAGS = "-Dmain=_single_binary_main_mkdir(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_mkdir" -Dusage=_usage_mkdir $(src_coreutils_CFLAGS)
+src_libsinglebin_mkdir_a_CFLAGS = "-Dmain=single_binary_main_mkdir (int, char **); int single_binary_main_mkdir" -Dusage=_usage_mkdir $(src_coreutils_CFLAGS)
# Command mkfifo
noinst_LIBRARIES += src/libsinglebin_mkfifo.a
src_libsinglebin_mkfifo_a_SOURCES = src/mkfifo.c $(selinux_sources)
src_libsinglebin_mkfifo_a_ldadd = $(LIB_SELINUX) $(LIB_SMACK)
-src_libsinglebin_mkfifo_a_CFLAGS = "-Dmain=_single_binary_main_mkfifo(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_mkfifo" -Dusage=_usage_mkfifo $(src_coreutils_CFLAGS)
+src_libsinglebin_mkfifo_a_CFLAGS = "-Dmain=single_binary_main_mkfifo (int, char **); int single_binary_main_mkfifo" -Dusage=_usage_mkfifo $(src_coreutils_CFLAGS)
# Command mknod
noinst_LIBRARIES += src/libsinglebin_mknod.a
src_libsinglebin_mknod_a_SOURCES = src/mknod.c $(selinux_sources)
src_libsinglebin_mknod_a_ldadd = $(LIB_SELINUX) $(LIB_SMACK)
-src_libsinglebin_mknod_a_CFLAGS = "-Dmain=_single_binary_main_mknod(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_mknod" -Dusage=_usage_mknod $(src_coreutils_CFLAGS)
+src_libsinglebin_mknod_a_CFLAGS = "-Dmain=single_binary_main_mknod (int, char **); int single_binary_main_mknod" -Dusage=_usage_mknod $(src_coreutils_CFLAGS)
# Command mktemp
noinst_LIBRARIES += src/libsinglebin_mktemp.a
src_libsinglebin_mktemp_a_SOURCES = src/mktemp.c
-src_libsinglebin_mktemp_a_CFLAGS = "-Dmain=_single_binary_main_mktemp(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_mktemp" -Dusage=_usage_mktemp $(src_coreutils_CFLAGS)
+src_libsinglebin_mktemp_a_CFLAGS = "-Dmain=single_binary_main_mktemp (int, char **); int single_binary_main_mktemp" -Dusage=_usage_mktemp $(src_coreutils_CFLAGS)
# Command mv
noinst_LIBRARIES += src/libsinglebin_mv.a
src_libsinglebin_mv_a_SOURCES = src/mv.c src/remove.c $(copy_sources) $(selinux_sources)
src_libsinglebin_mv_a_ldadd = $(copy_ldadd) $(remove_ldadd)
-src_libsinglebin_mv_a_CFLAGS = "-Dmain=_single_binary_main_mv(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_mv" -Dusage=_usage_mv $(src_coreutils_CFLAGS)
+src_libsinglebin_mv_a_CFLAGS = "-Dmain=single_binary_main_mv (int, char **); int single_binary_main_mv" -Dusage=_usage_mv $(src_coreutils_CFLAGS)
# Command nl
noinst_LIBRARIES += src/libsinglebin_nl.a
src_libsinglebin_nl_a_SOURCES = src/nl.c
-src_libsinglebin_nl_a_CFLAGS = "-Dmain=_single_binary_main_nl(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_nl" -Dusage=_usage_nl $(src_coreutils_CFLAGS)
+src_libsinglebin_nl_a_CFLAGS = "-Dmain=single_binary_main_nl (int, char **); int single_binary_main_nl" -Dusage=_usage_nl $(src_coreutils_CFLAGS)
# Command nproc
noinst_LIBRARIES += src/libsinglebin_nproc.a
src_libsinglebin_nproc_a_SOURCES = src/nproc.c
-src_libsinglebin_nproc_a_CFLAGS = "-Dmain=_single_binary_main_nproc(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_nproc" -Dusage=_usage_nproc $(src_coreutils_CFLAGS)
+src_libsinglebin_nproc_a_CFLAGS = "-Dmain=single_binary_main_nproc (int, char **); int single_binary_main_nproc" -Dusage=_usage_nproc $(src_coreutils_CFLAGS)
# Command nohup
noinst_LIBRARIES += src/libsinglebin_nohup.a
src_libsinglebin_nohup_a_SOURCES = src/nohup.c
-src_libsinglebin_nohup_a_CFLAGS = "-Dmain=_single_binary_main_nohup(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_nohup" -Dusage=_usage_nohup $(src_coreutils_CFLAGS)
+src_libsinglebin_nohup_a_CFLAGS = "-Dmain=single_binary_main_nohup (int, char **); int single_binary_main_nohup" -Dusage=_usage_nohup $(src_coreutils_CFLAGS)
# Command numfmt
noinst_LIBRARIES += src/libsinglebin_numfmt.a
src_libsinglebin_numfmt_a_SOURCES = src/numfmt.c
-src_libsinglebin_numfmt_a_CFLAGS = "-Dmain=_single_binary_main_numfmt(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_numfmt" -Dusage=_usage_numfmt $(src_coreutils_CFLAGS)
+src_libsinglebin_numfmt_a_CFLAGS = "-Dmain=single_binary_main_numfmt (int, char **); int single_binary_main_numfmt" -Dusage=_usage_numfmt $(src_coreutils_CFLAGS)
# Command od
noinst_LIBRARIES += src/libsinglebin_od.a
src_libsinglebin_od_a_SOURCES = src/od.c
-src_libsinglebin_od_a_CFLAGS = "-Dmain=_single_binary_main_od(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_od" -Dusage=_usage_od $(src_coreutils_CFLAGS)
+src_libsinglebin_od_a_CFLAGS = "-Dmain=single_binary_main_od (int, char **); int single_binary_main_od" -Dusage=_usage_od $(src_coreutils_CFLAGS)
# Command paste
noinst_LIBRARIES += src/libsinglebin_paste.a
src_libsinglebin_paste_a_SOURCES = src/paste.c
-src_libsinglebin_paste_a_CFLAGS = "-Dmain=_single_binary_main_paste(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_paste" -Dusage=_usage_paste $(src_coreutils_CFLAGS)
+src_libsinglebin_paste_a_CFLAGS = "-Dmain=single_binary_main_paste (int, char **); int single_binary_main_paste" -Dusage=_usage_paste $(src_coreutils_CFLAGS)
# Command pathchk
noinst_LIBRARIES += src/libsinglebin_pathchk.a
src_libsinglebin_pathchk_a_SOURCES = src/pathchk.c
-src_libsinglebin_pathchk_a_CFLAGS = "-Dmain=_single_binary_main_pathchk(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_pathchk" -Dusage=_usage_pathchk $(src_coreutils_CFLAGS)
+src_libsinglebin_pathchk_a_CFLAGS = "-Dmain=single_binary_main_pathchk (int, char **); int single_binary_main_pathchk" -Dusage=_usage_pathchk $(src_coreutils_CFLAGS)
# Command pr
noinst_LIBRARIES += src/libsinglebin_pr.a
src_libsinglebin_pr_a_SOURCES = src/pr.c
src_libsinglebin_pr_a_ldadd = $(LIB_CLOCK_GETTIME)
-src_libsinglebin_pr_a_CFLAGS = "-Dmain=_single_binary_main_pr(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_pr" -Dusage=_usage_pr $(src_coreutils_CFLAGS)
+src_libsinglebin_pr_a_CFLAGS = "-Dmain=single_binary_main_pr (int, char **); int single_binary_main_pr" -Dusage=_usage_pr $(src_coreutils_CFLAGS)
# Command printenv
noinst_LIBRARIES += src/libsinglebin_printenv.a
src_libsinglebin_printenv_a_SOURCES = src/printenv.c
-src_libsinglebin_printenv_a_CFLAGS = "-Dmain=_single_binary_main_printenv(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_printenv" -Dusage=_usage_printenv $(src_coreutils_CFLAGS)
+src_libsinglebin_printenv_a_CFLAGS = "-Dmain=single_binary_main_printenv (int, char **); int single_binary_main_printenv" -Dusage=_usage_printenv $(src_coreutils_CFLAGS)
# Command printf
noinst_LIBRARIES += src/libsinglebin_printf.a
src_libsinglebin_printf_a_SOURCES = src/printf.c
src_libsinglebin_printf_a_ldadd = $(LIBICONV)
-src_libsinglebin_printf_a_CFLAGS = "-Dmain=_single_binary_main_printf(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_printf" -Dusage=_usage_printf $(src_coreutils_CFLAGS)
+src_libsinglebin_printf_a_CFLAGS = "-Dmain=single_binary_main_printf (int, char **); int single_binary_main_printf" -Dusage=_usage_printf $(src_coreutils_CFLAGS)
# Command ptx
noinst_LIBRARIES += src/libsinglebin_ptx.a
src_libsinglebin_ptx_a_SOURCES = src/ptx.c
src_libsinglebin_ptx_a_ldadd = $(LIBICONV)
-src_libsinglebin_ptx_a_CFLAGS = "-Dmain=_single_binary_main_ptx(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_ptx" -Dusage=_usage_ptx $(src_coreutils_CFLAGS)
+src_libsinglebin_ptx_a_CFLAGS = "-Dmain=single_binary_main_ptx (int, char **); int single_binary_main_ptx" -Dusage=_usage_ptx $(src_coreutils_CFLAGS)
# Command pwd
noinst_LIBRARIES += src/libsinglebin_pwd.a
src_libsinglebin_pwd_a_SOURCES = src/pwd.c
-src_libsinglebin_pwd_a_CFLAGS = "-Dmain=_single_binary_main_pwd(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_pwd" -Dusage=_usage_pwd $(src_coreutils_CFLAGS)
+src_libsinglebin_pwd_a_CFLAGS = "-Dmain=single_binary_main_pwd (int, char **); int single_binary_main_pwd" -Dusage=_usage_pwd $(src_coreutils_CFLAGS)
# Command readlink
noinst_LIBRARIES += src/libsinglebin_readlink.a
src_libsinglebin_readlink_a_SOURCES = src/readlink.c
-src_libsinglebin_readlink_a_CFLAGS = "-Dmain=_single_binary_main_readlink(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_readlink" -Dusage=_usage_readlink $(src_coreutils_CFLAGS)
+src_libsinglebin_readlink_a_CFLAGS = "-Dmain=single_binary_main_readlink (int, char **); int single_binary_main_readlink" -Dusage=_usage_readlink $(src_coreutils_CFLAGS)
# Command realpath
noinst_LIBRARIES += src/libsinglebin_realpath.a
src_libsinglebin_realpath_a_SOURCES = src/realpath.c src/relpath.c src/relpath.h
src_libsinglebin_realpath_a_ldadd = $(LIBICONV)
-src_libsinglebin_realpath_a_CFLAGS = "-Dmain=_single_binary_main_realpath(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_realpath" -Dusage=_usage_realpath $(src_coreutils_CFLAGS)
+src_libsinglebin_realpath_a_CFLAGS = "-Dmain=single_binary_main_realpath (int, char **); int single_binary_main_realpath" -Dusage=_usage_realpath $(src_coreutils_CFLAGS)
# Command rm
noinst_LIBRARIES += src/libsinglebin_rm.a
src_libsinglebin_rm_a_SOURCES = src/rm.c src/remove.c
src_libsinglebin_rm_a_ldadd = $(remove_ldadd)
-src_libsinglebin_rm_a_CFLAGS = "-Dmain=_single_binary_main_rm(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_rm" -Dusage=_usage_rm $(src_coreutils_CFLAGS)
+src_libsinglebin_rm_a_CFLAGS = "-Dmain=single_binary_main_rm (int, char **); int single_binary_main_rm" -Dusage=_usage_rm $(src_coreutils_CFLAGS)
# Command rmdir
noinst_LIBRARIES += src/libsinglebin_rmdir.a
src_libsinglebin_rmdir_a_SOURCES = src/rmdir.c src/prog-fprintf.c
-src_libsinglebin_rmdir_a_CFLAGS = "-Dmain=_single_binary_main_rmdir(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_rmdir" -Dusage=_usage_rmdir $(src_coreutils_CFLAGS)
+src_libsinglebin_rmdir_a_CFLAGS = "-Dmain=single_binary_main_rmdir (int, char **); int single_binary_main_rmdir" -Dusage=_usage_rmdir $(src_coreutils_CFLAGS)
# Command runcon
noinst_LIBRARIES += src/libsinglebin_runcon.a
src_libsinglebin_runcon_a_SOURCES = src/runcon.c
src_libsinglebin_runcon_a_ldadd = $(LIB_SELINUX)
-src_libsinglebin_runcon_a_CFLAGS = "-Dmain=_single_binary_main_runcon(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_runcon" -Dusage=_usage_runcon $(src_coreutils_CFLAGS)
+src_libsinglebin_runcon_a_CFLAGS = "-Dmain=single_binary_main_runcon (int, char **); int single_binary_main_runcon" -Dusage=_usage_runcon $(src_coreutils_CFLAGS)
# Command seq
noinst_LIBRARIES += src/libsinglebin_seq.a
src_libsinglebin_seq_a_SOURCES = src/seq.c
-src_libsinglebin_seq_a_CFLAGS = "-Dmain=_single_binary_main_seq(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_seq" -Dusage=_usage_seq $(src_coreutils_CFLAGS)
+src_libsinglebin_seq_a_CFLAGS = "-Dmain=single_binary_main_seq (int, char **); int single_binary_main_seq" -Dusage=_usage_seq $(src_coreutils_CFLAGS)
# Command sha1sum
noinst_LIBRARIES += src/libsinglebin_sha1sum.a
src_libsinglebin_sha1sum_a_SOURCES = src/md5sum.c
src_libsinglebin_sha1sum_a_ldadd = $(LIB_CRYPTO)
-src_libsinglebin_sha1sum_a_CFLAGS = "-Dmain=_single_binary_main_sha1sum(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_sha1sum" -Dusage=_usage_sha1sum $(src_coreutils_CFLAGS)
+src_libsinglebin_sha1sum_a_CFLAGS = "-Dmain=single_binary_main_sha1sum (int, char **); int single_binary_main_sha1sum" -Dusage=_usage_sha1sum $(src_coreutils_CFLAGS)
src_libsinglebin_sha1sum_a_CPPFLAGS = -DHASH_ALGO_SHA1=1 $(AM_CPPFLAGS)
# Command sha224sum
noinst_LIBRARIES += src/libsinglebin_sha224sum.a
src_libsinglebin_sha224sum_a_SOURCES = src/md5sum.c
src_libsinglebin_sha224sum_a_ldadd = $(LIB_CRYPTO)
-src_libsinglebin_sha224sum_a_CFLAGS = "-Dmain=_single_binary_main_sha224sum(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_sha224sum" -Dusage=_usage_sha224sum $(src_coreutils_CFLAGS)
+src_libsinglebin_sha224sum_a_CFLAGS = "-Dmain=single_binary_main_sha224sum (int, char **); int single_binary_main_sha224sum" -Dusage=_usage_sha224sum $(src_coreutils_CFLAGS)
src_libsinglebin_sha224sum_a_CPPFLAGS = -DHASH_ALGO_SHA224=1 $(AM_CPPFLAGS)
# Command sha256sum
noinst_LIBRARIES += src/libsinglebin_sha256sum.a
src_libsinglebin_sha256sum_a_SOURCES = src/md5sum.c
src_libsinglebin_sha256sum_a_ldadd = $(LIB_CRYPTO)
-src_libsinglebin_sha256sum_a_CFLAGS = "-Dmain=_single_binary_main_sha256sum(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_sha256sum" -Dusage=_usage_sha256sum $(src_coreutils_CFLAGS)
+src_libsinglebin_sha256sum_a_CFLAGS = "-Dmain=single_binary_main_sha256sum (int, char **); int single_binary_main_sha256sum" -Dusage=_usage_sha256sum $(src_coreutils_CFLAGS)
src_libsinglebin_sha256sum_a_CPPFLAGS = -DHASH_ALGO_SHA256=1 $(AM_CPPFLAGS)
# Command sha384sum
noinst_LIBRARIES += src/libsinglebin_sha384sum.a
src_libsinglebin_sha384sum_a_SOURCES = src/md5sum.c
src_libsinglebin_sha384sum_a_ldadd = $(LIB_CRYPTO)
-src_libsinglebin_sha384sum_a_CFLAGS = "-Dmain=_single_binary_main_sha384sum(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_sha384sum" -Dusage=_usage_sha384sum $(src_coreutils_CFLAGS)
+src_libsinglebin_sha384sum_a_CFLAGS = "-Dmain=single_binary_main_sha384sum (int, char **); int single_binary_main_sha384sum" -Dusage=_usage_sha384sum $(src_coreutils_CFLAGS)
src_libsinglebin_sha384sum_a_CPPFLAGS = -DHASH_ALGO_SHA384=1 $(AM_CPPFLAGS)
# Command sha512sum
noinst_LIBRARIES += src/libsinglebin_sha512sum.a
src_libsinglebin_sha512sum_a_SOURCES = src/md5sum.c
src_libsinglebin_sha512sum_a_ldadd = $(LIB_CRYPTO)
-src_libsinglebin_sha512sum_a_CFLAGS = "-Dmain=_single_binary_main_sha512sum(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_sha512sum" -Dusage=_usage_sha512sum $(src_coreutils_CFLAGS)
+src_libsinglebin_sha512sum_a_CFLAGS = "-Dmain=single_binary_main_sha512sum (int, char **); int single_binary_main_sha512sum" -Dusage=_usage_sha512sum $(src_coreutils_CFLAGS)
src_libsinglebin_sha512sum_a_CPPFLAGS = -DHASH_ALGO_SHA512=1 $(AM_CPPFLAGS)
# Command shred
noinst_LIBRARIES += src/libsinglebin_shred.a
src_libsinglebin_shred_a_SOURCES = src/shred.c
src_libsinglebin_shred_a_ldadd = $(LIB_FDATASYNC)
-src_libsinglebin_shred_a_CFLAGS = "-Dmain=_single_binary_main_shred(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_shred" -Dusage=_usage_shred $(src_coreutils_CFLAGS)
+src_libsinglebin_shred_a_CFLAGS = "-Dmain=single_binary_main_shred (int, char **); int single_binary_main_shred" -Dusage=_usage_shred $(src_coreutils_CFLAGS)
# Command shuf
noinst_LIBRARIES += src/libsinglebin_shuf.a
src_libsinglebin_shuf_a_SOURCES = src/shuf.c
-src_libsinglebin_shuf_a_CFLAGS = "-Dmain=_single_binary_main_shuf(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_shuf" -Dusage=_usage_shuf $(src_coreutils_CFLAGS)
+src_libsinglebin_shuf_a_CFLAGS = "-Dmain=single_binary_main_shuf (int, char **); int single_binary_main_shuf" -Dusage=_usage_shuf $(src_coreutils_CFLAGS)
# Command sleep
noinst_LIBRARIES += src/libsinglebin_sleep.a
src_libsinglebin_sleep_a_SOURCES = src/sleep.c
src_libsinglebin_sleep_a_ldadd = $(LIB_NANOSLEEP)
-src_libsinglebin_sleep_a_CFLAGS = "-Dmain=_single_binary_main_sleep(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_sleep" -Dusage=_usage_sleep $(src_coreutils_CFLAGS)
+src_libsinglebin_sleep_a_CFLAGS = "-Dmain=single_binary_main_sleep (int, char **); int single_binary_main_sleep" -Dusage=_usage_sleep $(src_coreutils_CFLAGS)
# Command sort
noinst_LIBRARIES += src/libsinglebin_sort.a
src_libsinglebin_sort_a_SOURCES = src/sort.c
src_libsinglebin_sort_a_ldadd = $(LIB_EACCESS) $(LIB_NANOSLEEP) $(LIB_CRYPTO) $(LIB_PTHREAD)
-src_libsinglebin_sort_a_CFLAGS = "-Dmain=_single_binary_main_sort(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_sort" -Dusage=_usage_sort $(src_coreutils_CFLAGS)
+src_libsinglebin_sort_a_CFLAGS = "-Dmain=single_binary_main_sort (int, char **); int single_binary_main_sort" -Dusage=_usage_sort $(src_coreutils_CFLAGS)
# Command split
noinst_LIBRARIES += src/libsinglebin_split.a
src_libsinglebin_split_a_SOURCES = src/split.c
src_libsinglebin_split_a_ldadd = $(LIBICONV)
-src_libsinglebin_split_a_CFLAGS = "-Dmain=_single_binary_main_split(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_split" -Dusage=_usage_split $(src_coreutils_CFLAGS)
+src_libsinglebin_split_a_CFLAGS = "-Dmain=single_binary_main_split (int, char **); int single_binary_main_split" -Dusage=_usage_split $(src_coreutils_CFLAGS)
# Command stat
noinst_LIBRARIES += src/libsinglebin_stat.a
src_libsinglebin_stat_a_SOURCES = src/stat.c src/find-mount-point.c
src_libsinglebin_stat_a_ldadd = $(LIB_SELINUX) $(LIB_NVPAIR)
-src_libsinglebin_stat_a_CFLAGS = "-Dmain=_single_binary_main_stat(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_stat" -Dusage=_usage_stat $(src_coreutils_CFLAGS)
+src_libsinglebin_stat_a_CFLAGS = "-Dmain=single_binary_main_stat (int, char **); int single_binary_main_stat" -Dusage=_usage_stat $(src_coreutils_CFLAGS)
# Command sum
noinst_LIBRARIES += src/libsinglebin_sum.a
src_libsinglebin_sum_a_SOURCES = src/sum.c
-src_libsinglebin_sum_a_CFLAGS = "-Dmain=_single_binary_main_sum(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_sum" -Dusage=_usage_sum $(src_coreutils_CFLAGS)
+src_libsinglebin_sum_a_CFLAGS = "-Dmain=single_binary_main_sum (int, char **); int single_binary_main_sum" -Dusage=_usage_sum $(src_coreutils_CFLAGS)
# Command sync
noinst_LIBRARIES += src/libsinglebin_sync.a
src_libsinglebin_sync_a_SOURCES = src/sync.c
-src_libsinglebin_sync_a_CFLAGS = "-Dmain=_single_binary_main_sync(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_sync" -Dusage=_usage_sync $(src_coreutils_CFLAGS)
+src_libsinglebin_sync_a_CFLAGS = "-Dmain=single_binary_main_sync (int, char **); int single_binary_main_sync" -Dusage=_usage_sync $(src_coreutils_CFLAGS)
# Command tac
noinst_LIBRARIES += src/libsinglebin_tac.a
src_libsinglebin_tac_a_SOURCES = src/tac.c
-src_libsinglebin_tac_a_CFLAGS = "-Dmain=_single_binary_main_tac(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_tac" -Dusage=_usage_tac $(src_coreutils_CFLAGS)
+src_libsinglebin_tac_a_CFLAGS = "-Dmain=single_binary_main_tac (int, char **); int single_binary_main_tac" -Dusage=_usage_tac $(src_coreutils_CFLAGS)
# Command tail
noinst_LIBRARIES += src/libsinglebin_tail.a
src_libsinglebin_tail_a_SOURCES = src/tail.c
src_libsinglebin_tail_a_ldadd = $(LIB_NANOSLEEP)
-src_libsinglebin_tail_a_CFLAGS = "-Dmain=_single_binary_main_tail(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_tail" -Dusage=_usage_tail $(src_coreutils_CFLAGS)
+src_libsinglebin_tail_a_CFLAGS = "-Dmain=single_binary_main_tail (int, char **); int single_binary_main_tail" -Dusage=_usage_tail $(src_coreutils_CFLAGS)
# Command tee
noinst_LIBRARIES += src/libsinglebin_tee.a
src_libsinglebin_tee_a_SOURCES = src/tee.c
-src_libsinglebin_tee_a_CFLAGS = "-Dmain=_single_binary_main_tee(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_tee" -Dusage=_usage_tee $(src_coreutils_CFLAGS)
+src_libsinglebin_tee_a_CFLAGS = "-Dmain=single_binary_main_tee (int, char **); int single_binary_main_tee" -Dusage=_usage_tee $(src_coreutils_CFLAGS)
# Command test
noinst_LIBRARIES += src/libsinglebin_test.a
src_libsinglebin_test_a_SOURCES = src/test.c
src_libsinglebin_test_a_ldadd = $(LIB_EACCESS)
-src_libsinglebin_test_a_CFLAGS = "-Dmain=_single_binary_main_test(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_test" -Dusage=_usage_test $(src_coreutils_CFLAGS)
+src_libsinglebin_test_a_CFLAGS = "-Dmain=single_binary_main_test (int, char **); int single_binary_main_test" -Dusage=_usage_test $(src_coreutils_CFLAGS)
# Command timeout
noinst_LIBRARIES += src/libsinglebin_timeout.a
src_libsinglebin_timeout_a_SOURCES = src/timeout.c src/operand2sig.c
src_libsinglebin_timeout_a_ldadd = $(LIB_TIMER_TIME) $(LIBICONV)
-src_libsinglebin_timeout_a_CFLAGS = "-Dmain=_single_binary_main_timeout(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_timeout" -Dusage=_usage_timeout $(src_coreutils_CFLAGS)
+src_libsinglebin_timeout_a_CFLAGS = "-Dmain=single_binary_main_timeout (int, char **); int single_binary_main_timeout" -Dusage=_usage_timeout $(src_coreutils_CFLAGS)
# Command touch
noinst_LIBRARIES += src/libsinglebin_touch.a
src_libsinglebin_touch_a_SOURCES = src/touch.c
src_libsinglebin_touch_a_ldadd = $(LIB_CLOCK_GETTIME)
-src_libsinglebin_touch_a_CFLAGS = "-Dmain=_single_binary_main_touch(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_touch" -Dusage=_usage_touch $(src_coreutils_CFLAGS)
+src_libsinglebin_touch_a_CFLAGS = "-Dmain=single_binary_main_touch (int, char **); int single_binary_main_touch" -Dusage=_usage_touch $(src_coreutils_CFLAGS)
# Command tr
noinst_LIBRARIES += src/libsinglebin_tr.a
src_libsinglebin_tr_a_SOURCES = src/tr.c
-src_libsinglebin_tr_a_CFLAGS = "-Dmain=_single_binary_main_tr(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_tr" -Dusage=_usage_tr $(src_coreutils_CFLAGS)
+src_libsinglebin_tr_a_CFLAGS = "-Dmain=single_binary_main_tr (int, char **); int single_binary_main_tr" -Dusage=_usage_tr $(src_coreutils_CFLAGS)
# Command true
noinst_LIBRARIES += src/libsinglebin_true.a
src_libsinglebin_true_a_SOURCES = src/true.c
-src_libsinglebin_true_a_CFLAGS = "-Dmain=_single_binary_main_true(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_true" -Dusage=_usage_true $(src_coreutils_CFLAGS)
+src_libsinglebin_true_a_CFLAGS = "-Dmain=single_binary_main_true (int, char **); int single_binary_main_true" -Dusage=_usage_true $(src_coreutils_CFLAGS)
# Command truncate
noinst_LIBRARIES += src/libsinglebin_truncate.a
src_libsinglebin_truncate_a_SOURCES = src/truncate.c
src_libsinglebin_truncate_a_ldadd = $(LIBICONV)
-src_libsinglebin_truncate_a_CFLAGS = "-Dmain=_single_binary_main_truncate(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_truncate" -Dusage=_usage_truncate $(src_coreutils_CFLAGS)
+src_libsinglebin_truncate_a_CFLAGS = "-Dmain=single_binary_main_truncate (int, char **); int single_binary_main_truncate" -Dusage=_usage_truncate $(src_coreutils_CFLAGS)
# Command tsort
noinst_LIBRARIES += src/libsinglebin_tsort.a
src_libsinglebin_tsort_a_SOURCES = src/tsort.c
-src_libsinglebin_tsort_a_CFLAGS = "-Dmain=_single_binary_main_tsort(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_tsort" -Dusage=_usage_tsort $(src_coreutils_CFLAGS)
+src_libsinglebin_tsort_a_CFLAGS = "-Dmain=single_binary_main_tsort (int, char **); int single_binary_main_tsort" -Dusage=_usage_tsort $(src_coreutils_CFLAGS)
# Command tty
noinst_LIBRARIES += src/libsinglebin_tty.a
src_libsinglebin_tty_a_SOURCES = src/tty.c
-src_libsinglebin_tty_a_CFLAGS = "-Dmain=_single_binary_main_tty(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_tty" -Dusage=_usage_tty $(src_coreutils_CFLAGS)
+src_libsinglebin_tty_a_CFLAGS = "-Dmain=single_binary_main_tty (int, char **); int single_binary_main_tty" -Dusage=_usage_tty $(src_coreutils_CFLAGS)
# Command uname
noinst_LIBRARIES += src/libsinglebin_uname.a
src_libsinglebin_uname_a_SOURCES = src/uname.c src/uname-uname.c
src_libsinglebin_uname_a_ldadd = $(GETHOSTNAME_LIB)
-src_libsinglebin_uname_a_CFLAGS = "-Dmain=_single_binary_main_uname(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_uname" -Dusage=_usage_uname $(src_coreutils_CFLAGS)
+src_libsinglebin_uname_a_CFLAGS = "-Dmain=single_binary_main_uname (int, char **); int single_binary_main_uname" -Dusage=_usage_uname $(src_coreutils_CFLAGS)
# Command unexpand
noinst_LIBRARIES += src/libsinglebin_unexpand.a
src_libsinglebin_unexpand_a_SOURCES = src/unexpand.c
-src_libsinglebin_unexpand_a_CFLAGS = "-Dmain=_single_binary_main_unexpand(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_unexpand" -Dusage=_usage_unexpand $(src_coreutils_CFLAGS)
+src_libsinglebin_unexpand_a_CFLAGS = "-Dmain=single_binary_main_unexpand (int, char **); int single_binary_main_unexpand" -Dusage=_usage_unexpand $(src_coreutils_CFLAGS)
# Command uniq
noinst_LIBRARIES += src/libsinglebin_uniq.a
src_libsinglebin_uniq_a_SOURCES = src/uniq.c
-src_libsinglebin_uniq_a_CFLAGS = "-Dmain=_single_binary_main_uniq(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_uniq" -Dusage=_usage_uniq $(src_coreutils_CFLAGS)
+src_libsinglebin_uniq_a_CFLAGS = "-Dmain=single_binary_main_uniq (int, char **); int single_binary_main_uniq" -Dusage=_usage_uniq $(src_coreutils_CFLAGS)
# Command unlink
noinst_LIBRARIES += src/libsinglebin_unlink.a
src_libsinglebin_unlink_a_SOURCES = src/unlink.c
-src_libsinglebin_unlink_a_CFLAGS = "-Dmain=_single_binary_main_unlink(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_unlink" -Dusage=_usage_unlink $(src_coreutils_CFLAGS)
+src_libsinglebin_unlink_a_CFLAGS = "-Dmain=single_binary_main_unlink (int, char **); int single_binary_main_unlink" -Dusage=_usage_unlink $(src_coreutils_CFLAGS)
# Command vdir
noinst_LIBRARIES += src/libsinglebin_vdir.a
src_libsinglebin_vdir_a_SOURCES = src/coreutils-vdir.c
src_libsinglebin_vdir_a_ldadd = $(src_ls_LDADD) src/libsinglebin_ls.a
-src_libsinglebin_vdir_a_CFLAGS = "-Dmain=_single_binary_main_vdir(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_vdir" -Dusage=_usage_vdir $(src_coreutils_CFLAGS)
+src_libsinglebin_vdir_a_CFLAGS = "-Dmain=single_binary_main_vdir (int, char **); int single_binary_main_vdir" -Dusage=_usage_vdir $(src_coreutils_CFLAGS)
# Command wc
noinst_LIBRARIES += src/libsinglebin_wc.a
src_libsinglebin_wc_a_SOURCES = src/wc.c
-src_libsinglebin_wc_a_CFLAGS = "-Dmain=_single_binary_main_wc(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_wc" -Dusage=_usage_wc $(src_coreutils_CFLAGS)
+src_libsinglebin_wc_a_CFLAGS = "-Dmain=single_binary_main_wc (int, char **); int single_binary_main_wc" -Dusage=_usage_wc $(src_coreutils_CFLAGS)
# Command whoami
noinst_LIBRARIES += src/libsinglebin_whoami.a
src_libsinglebin_whoami_a_SOURCES = src/whoami.c
-src_libsinglebin_whoami_a_CFLAGS = "-Dmain=_single_binary_main_whoami(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_whoami" -Dusage=_usage_whoami $(src_coreutils_CFLAGS)
+src_libsinglebin_whoami_a_CFLAGS = "-Dmain=single_binary_main_whoami (int, char **); int single_binary_main_whoami" -Dusage=_usage_whoami $(src_coreutils_CFLAGS)
# Command yes
noinst_LIBRARIES += src/libsinglebin_yes.a
src_libsinglebin_yes_a_SOURCES = src/yes.c
-src_libsinglebin_yes_a_CFLAGS = "-Dmain=_single_binary_main_yes(int, char**) ATTRIBUTE_NORETURN; int _single_binary_main_yes" -Dusage=_usage_yes $(src_coreutils_CFLAGS)
+src_libsinglebin_yes_a_CFLAGS = "-Dmain=single_binary_main_yes (int, char **); int single_binary_main_yes" -Dusage=_usage_yes $(src_coreutils_CFLAGS)
diff --git a/src/sleep.c b/src/sleep.c
index e24c2512..788601be 100644
--- a/src/sleep.c
+++ b/src/sleep.c
@@ -1,5 +1,5 @@
/* sleep - delay for a specified amount of time.
- Copyright (C) 1984-2014 Free Software Foundation, Inc.
+ Copyright (C) 1984-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -54,7 +54,7 @@ specified by the sum of their values.\n\
program_name, program_name);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -145,5 +145,5 @@ main (int argc, char **argv)
if (xnanosleep (seconds))
error (EXIT_FAILURE, errno, _("cannot read realtime clock"));
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/sort.c b/src/sort.c
index c2493192..85fc38f7 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -1,5 +1,5 @@
/* sort - sort lines of text (with all kinds of options).
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -428,6 +428,7 @@ Usage: %s [OPTION]... [FILE]...\n\
Write sorted concatenation of all FILE(s) to standard output.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -524,14 +525,12 @@ SIZE may be followed by the following multiplicative suffixes:\n\
fputs (_("\
% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y.\n\
\n\
-With no FILE, or when FILE is -, read standard input.\n\
-\n\
*** WARNING ***\n\
The locale specified by the environment affects sort order.\n\
Set LC_ALL=C to get the traditional sort order that uses\n\
native byte values.\n\
"), stdout );
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
@@ -4708,7 +4707,7 @@ main (int argc, char **argv)
/* POSIX requires that sort return 1 IFF invoked with -c or -C and the
input is not properly sorted. */
- exit (check (files[0], checkonly) ? EXIT_SUCCESS : SORT_OUT_OF_ORDER);
+ return check (files[0], checkonly) ? EXIT_SUCCESS : SORT_OUT_OF_ORDER;
}
/* Check all inputs are accessible, or exit immediately. */
@@ -4746,5 +4745,5 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) == EOF)
die (_("close failed"), "-");
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/split.c b/src/split.c
index dacacaa8..35f2629a 100644
--- a/src/split.c
+++ b/src/split.c
@@ -1,5 +1,5 @@
/* split.c -- split a file into pieces.
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,10 +16,9 @@
/* By tege@sics.se, with rms.
- To do:
- * Implement -t CHAR or -t REGEX to specify break characters other
- than newline. */
-
+ TODO:
+ * support -p REGEX as in BSD's split.
+ * support --suppress-matched as in csplit. */
#include <config.h>
#include <assert.h>
@@ -39,6 +38,7 @@
#include "safe-read.h"
#include "sig2str.h"
#include "xfreopen.h"
+#include "xdectoint.h"
#include "xstrtol.h"
/* The official name of this program (e.g., no 'g' prefix). */
@@ -108,6 +108,9 @@ static bool elide_empty_files;
input to output, which is much slower, so disabled by default. */
static bool unbuffered;
+/* The character marking end of line. Defaults to \n below. */
+static int eolchar = -1;
+
/* The split mode to use. */
enum Split_type
{
@@ -139,6 +142,7 @@ static struct option const longopts[] =
{"numeric-suffixes", optional_argument, NULL, 'd'},
{"filter", required_argument, NULL, FILTER_OPTION},
{"verbose", no_argument, NULL, VERBOSE_OPTION},
+ {"separator", required_argument, NULL, 't'},
{"-io-blksize", required_argument, NULL,
IO_BLKSIZE_OPTION}, /* do not document */
{GETOPT_HELP_OPTION_DECL},
@@ -158,7 +162,7 @@ set_suffix_length (uintmax_t n_units, enum Split_type split_type)
{
#define DEFAULT_SUFFIX_LENGTH 2
- size_t suffix_needed = 0;
+ uintmax_t suffix_needed = 0;
/* The suffix auto length feature is incompatible with
a user specified start value as the generated suffixes
@@ -170,9 +174,26 @@ set_suffix_length (uintmax_t n_units, enum Split_type split_type)
if (split_type == type_chunk_bytes || split_type == type_chunk_lines
|| split_type == type_rr)
{
+ uintmax_t n_units_end = n_units;
+ if (numeric_suffix_start)
+ {
+ uintmax_t n_start;
+ strtol_error e = xstrtoumax (numeric_suffix_start, NULL, 10,
+ &n_start, "");
+ if (e == LONGINT_OK && n_start <= UINTMAX_MAX - n_units)
+ {
+ /* Restrict auto adjustment so we don't keep
+ incrementing a suffix size arbitrarily,
+ as that would break sort order for files
+ generated from multiple split runs. */
+ if (n_start < n_units)
+ n_units_end += n_start;
+ }
+
+ }
size_t alphabet_len = strlen (suffix_alphabet);
- bool alphabet_slop = (n_units % alphabet_len) != 0;
- while (n_units /= alphabet_len)
+ bool alphabet_slop = (n_units_end % alphabet_len) != 0;
+ while (n_units_end /= alphabet_len)
suffix_needed++;
suffix_needed += alphabet_slop;
suffix_auto = false;
@@ -183,7 +204,7 @@ set_suffix_length (uintmax_t n_units, enum Split_type split_type)
if (suffix_length < suffix_needed)
{
error (EXIT_FAILURE, 0,
- _("the suffix length needs to be at least %zu"),
+ _("the suffix length needs to be at least %"PRIuMAX),
suffix_needed);
}
suffix_auto = false;
@@ -201,28 +222,30 @@ usage (int status)
else
{
printf (_("\
-Usage: %s [OPTION]... [INPUT [PREFIX]]\n\
+Usage: %s [OPTION]... [FILE [PREFIX]]\n\
"),
program_name);
fputs (_("\
-Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default\n\
-size is 1000 lines, and default PREFIX is 'x'. With no INPUT, or when INPUT\n\
-is -, read standard input.\n\
+Output pieces of FILE to PREFIXaa, PREFIXab, ...;\n\
+default size is 1000 lines, and default PREFIX is 'x'.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fprintf (stdout, _("\
-a, --suffix-length=N generate suffixes of length N (default %d)\n\
--additional-suffix=SUFFIX append an additional SUFFIX to file names\n\
-b, --bytes=SIZE put SIZE bytes per output file\n\
- -C, --line-bytes=SIZE put at most SIZE bytes of lines per output file\n\
+ -C, --line-bytes=SIZE put at most SIZE bytes of records per output file\n\
-d, --numeric-suffixes[=FROM] use numeric suffixes instead of alphabetic;\n\
FROM changes the start value (default 0)\n\
-e, --elide-empty-files do not generate empty output files with '-n'\n\
--filter=COMMAND write to shell COMMAND; file name is $FILE\n\
- -l, --lines=NUMBER put NUMBER lines per output file\n\
+ -l, --lines=NUMBER put NUMBER lines/records per output file\n\
-n, --number=CHUNKS generate CHUNKS output files; see explanation below\n\
+ -t, --separator=SEP use SEP instead of newline as the record separator;\n\
+ '\\0' (zero) specifies the NUL character\n\
-u, --unbuffered immediately copy input to output with '-n r/...'\n\
"), DEFAULT_SUFFIX_LENGTH);
fputs (_("\
@@ -234,18 +257,49 @@ is -, read standard input.\n\
emit_size_note ();
fputs (_("\n\
CHUNKS may be:\n\
-N split into N files based on size of input\n\
-K/N output Kth of N to stdout\n\
-l/N split into N files without splitting lines\n\
-l/K/N output Kth of N to stdout without splitting lines\n\
-r/N like 'l' but use round robin distribution\n\
-r/K/N likewise but only output Kth of N to stdout\n\
+ N split into N files based on size of input\n\
+ K/N output Kth of N to stdout\n\
+ l/N split into N files without splitting lines/records\n\
+ l/K/N output Kth of N to stdout without splitting lines/records\n\
+ r/N like 'l' but use round robin distribution\n\
+ r/K/N likewise but only output Kth of N to stdout\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
+/* Return the number of bytes that can be read from FD, a file with
+ apparent size SIZE. Actually read the data into BUF (of size
+ BUFSIZE) if the file appears to be smaller than BUFSIZE, as this
+ works better on proc-like file systems. If the returned value is
+ less than BUFSIZE, store all the file's data into BUF; otherwise,
+ restore the input file's position so that the file can be reread if
+ needed. */
+
+static off_t
+input_file_size (int fd, off_t size, char *buf, size_t bufsize)
+{
+ if (size < bufsize)
+ {
+ size = 0;
+ while (true)
+ {
+ size_t save = size < bufsize ? size : 0;
+ size_t n_read = safe_read (fd, buf + save, bufsize - save);
+ if (n_read == 0)
+ break;
+ if (n_read == SAFE_READ_ERROR)
+ error (EXIT_FAILURE, errno, "%s", infile);
+ size += n_read;
+ }
+ if (bufsize <= size && lseek (fd, - size, SEEK_CUR) < 0)
+ error (EXIT_FAILURE, errno, "%s", infile);
+ }
+
+ return size;
+}
+
/* Compute the next sequential output file name and store it into the
string 'outfile'. */
@@ -485,7 +539,7 @@ closeout (FILE *fp, int fd, pid_t pid, char const *name)
{
/* shouldn't happen. */
error (EXIT_FAILURE, 0,
- _("unknown status from command (0x%X)"), wstatus);
+ _("unknown status from command (0x%X)"), wstatus + 0u);
}
}
}
@@ -511,10 +565,13 @@ cwrite (bool new_file_flag, const char *bp, size_t bytes)
}
/* Split into pieces of exactly N_BYTES bytes.
- Use buffer BUF, whose size is BUFSIZE. */
+ Use buffer BUF, whose size is BUFSIZE.
+ If INITIAL_READ != SIZE_MAX, the entire input file has already been
+ partly read into BUF and BUF contains INITIAL_READ input bytes. */
static void
-bytes_split (uintmax_t n_bytes, char *buf, size_t bufsize, uintmax_t max_files)
+bytes_split (uintmax_t n_bytes, char *buf, size_t bufsize, size_t initial_read,
+ uintmax_t max_files)
{
size_t n_read;
bool new_file_flag = true;
@@ -525,9 +582,17 @@ bytes_split (uintmax_t n_bytes, char *buf, size_t bufsize, uintmax_t max_files)
do
{
- n_read = safe_read (STDIN_FILENO, buf, bufsize);
- if (n_read == SAFE_READ_ERROR)
- error (EXIT_FAILURE, errno, "%s", infile);
+ if (initial_read != SIZE_MAX)
+ {
+ n_read = initial_read;
+ initial_read = SIZE_MAX;
+ }
+ else
+ {
+ n_read = safe_read (STDIN_FILENO, buf, bufsize);
+ if (n_read == SAFE_READ_ERROR)
+ error (EXIT_FAILURE, errno, "%s", infile);
+ }
bp_out = buf;
to_read = n_read;
while (true)
@@ -588,10 +653,10 @@ lines_split (uintmax_t n_lines, char *buf, size_t bufsize)
error (EXIT_FAILURE, errno, "%s", infile);
bp = bp_out = buf;
eob = bp + n_read;
- *eob = '\n';
+ *eob = eolchar;
while (true)
{
- bp = memchr (bp, '\n', eob - bp + 1);
+ bp = memchr (bp, eolchar, eob - bp + 1);
if (bp == eob)
{
if (eob != bp_out) /* do not write 0 bytes! */
@@ -650,10 +715,10 @@ line_bytes_split (uintmax_t n_bytes, char *buf, size_t bufsize)
/* Have enough for split. */
split_rest = n_bytes - n_out - n_hold;
eoc = sob + split_rest - 1;
- eol = memrchr (sob, '\n', split_rest);
+ eol = memrchr (sob, eolchar, split_rest);
}
else
- eol = memrchr (sob, '\n', n_left);
+ eol = memrchr (sob, eolchar, n_left);
/* Output hold space if possible. */
if (n_hold && !(!eol && n_out))
@@ -736,7 +801,7 @@ line_bytes_split (uintmax_t n_bytes, char *buf, size_t bufsize)
static void
lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
- off_t file_size)
+ size_t initial_read, off_t file_size)
{
assert (n && k <= n && n <= file_size);
@@ -751,7 +816,12 @@ lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
{
/* Start reading 1 byte before kth chunk of file. */
off_t start = (k - 1) * chunk_size - 1;
- if (lseek (STDIN_FILENO, start, SEEK_CUR) < 0)
+ if (initial_read != SIZE_MAX)
+ {
+ memmove (buf, buf + start, initial_read - start);
+ initial_read -= start;
+ }
+ else if (lseek (STDIN_FILENO, start, SEEK_CUR) < 0)
error (EXIT_FAILURE, errno, "%s", infile);
n_written = start;
chunk_no = k - 1;
@@ -761,10 +831,19 @@ lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
while (n_written < file_size)
{
char *bp = buf, *eob;
- size_t n_read = safe_read (STDIN_FILENO, buf, bufsize);
- if (n_read == SAFE_READ_ERROR)
- error (EXIT_FAILURE, errno, "%s", infile);
- else if (n_read == 0)
+ size_t n_read;
+ if (initial_read != SIZE_MAX)
+ {
+ n_read = initial_read;
+ initial_read = SIZE_MAX;
+ }
+ else
+ {
+ n_read = safe_read (STDIN_FILENO, buf, bufsize);
+ if (n_read == SAFE_READ_ERROR)
+ error (EXIT_FAILURE, errno, "%s", infile);
+ }
+ if (n_read == 0)
break; /* eof. */
n_read = MIN (n_read, file_size - n_written);
chunk_truncated = false;
@@ -777,7 +856,7 @@ lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
/* Begin looking for '\n' at last byte of chunk. */
off_t skip = MIN (n_read, MAX (0, chunk_end - n_written));
- char *bp_out = memchr (bp + skip, '\n', n_read - skip);
+ char *bp_out = memchr (bp + skip, eolchar, n_read - skip);
if (bp_out++)
next = true;
else
@@ -841,7 +920,7 @@ lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
static void
bytes_chunk_extract (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
- off_t file_size)
+ size_t initial_read, off_t file_size)
{
off_t start;
off_t end;
@@ -851,15 +930,29 @@ bytes_chunk_extract (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
start = (k - 1) * (file_size / n);
end = (k == n) ? file_size : k * (file_size / n);
- if (lseek (STDIN_FILENO, start, SEEK_CUR) < 0)
+ if (initial_read != SIZE_MAX)
+ {
+ memmove (buf, buf + start, initial_read - start);
+ initial_read -= start;
+ }
+ else if (lseek (STDIN_FILENO, start, SEEK_CUR) < 0)
error (EXIT_FAILURE, errno, "%s", infile);
while (start < end)
{
- size_t n_read = safe_read (STDIN_FILENO, buf, bufsize);
- if (n_read == SAFE_READ_ERROR)
- error (EXIT_FAILURE, errno, "%s", infile);
- else if (n_read == 0)
+ size_t n_read;
+ if (initial_read != SIZE_MAX)
+ {
+ n_read = initial_read;
+ initial_read = SIZE_MAX;
+ }
+ else
+ {
+ n_read = safe_read (STDIN_FILENO, buf, bufsize);
+ if (n_read == SAFE_READ_ERROR)
+ error (EXIT_FAILURE, errno, "%s", infile);
+ }
+ if (n_read == 0)
break; /* eof. */
n_read = MIN (n_read, end - start);
if (full_write (STDOUT_FILENO, buf, n_read) != n_read
@@ -915,11 +1008,11 @@ ofile_open (of_t *files, size_t i_check, size_t nfiles)
In specialised cases the consumer can keep reading
from the fifo, terminating on conditions in the data
itself, or perhaps never in the case of 'tail -f'.
- I.E. for fifos it is valid to attempt this reopen.
+ I.e., for fifos it is valid to attempt this reopen.
We don't handle the filter_command case here, as create()
will exit if there are not enough files in that case.
- I.E. we don't support restarting filters, as that would
+ I.e., we don't support restarting filters, as that would
put too much burden on users specifying --filter commands. */
fd = open (files[i_check].of_name,
O_WRONLY | O_BINARY | O_APPEND | O_NONBLOCK);
@@ -1010,7 +1103,7 @@ lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t bufsize)
bool next = false;
/* Find end of line. */
- char *bp_out = memchr (bp, '\n', eob - bp);
+ char *bp_out = memchr (bp, eolchar, eob - bp);
if (bp_out)
{
bp_out++;
@@ -1104,19 +1197,20 @@ no_filters:
} \
while (0)
+
/* Parse K/N syntax of chunk options. */
static void
parse_chunk (uintmax_t *k_units, uintmax_t *n_units, char *slash)
{
- *slash = '\0';
- if (xstrtoumax (slash + 1, NULL, 10, n_units, "") != LONGINT_OK
- || *n_units == 0)
- error (EXIT_FAILURE, 0, _("%s: invalid number of chunks"), slash + 1);
- if (slash != optarg /* a leading number is specified. */
- && (xstrtoumax (optarg, NULL, 10, k_units, "") != LONGINT_OK
- || *k_units == 0 || *n_units < *k_units))
- error (EXIT_FAILURE, 0, _("%s: invalid chunk number"), optarg);
+ *n_units = xdectoumax (slash + 1, 1, UINTMAX_MAX, "",
+ _("invalid number of chunks"), 0);
+ if (slash != optarg) /* a leading number is specified. */
+ {
+ *slash = '\0';
+ *k_units = xdectoumax (optarg, 1, *n_units, "",
+ _("invalid chunk number"), 0);
+ }
}
@@ -1127,7 +1221,7 @@ main (int argc, char **argv)
size_t in_blk_size = 0; /* optimal block size of input file device */
size_t page_size = getpagesize ();
uintmax_t k_units = 0;
- uintmax_t n_units;
+ uintmax_t n_units = 0;
static char const multipliers[] = "bEGKkMmPTYZ0";
int c;
@@ -1153,7 +1247,7 @@ main (int argc, char **argv)
int this_optind = optind ? optind : 1;
char *slash;
- c = getopt_long (argc, argv, "0123456789C:a:b:del:n:u",
+ c = getopt_long (argc, argv, "0123456789C:a:b:del:n:t:u",
longopts, NULL);
if (c == -1)
break;
@@ -1161,16 +1255,8 @@ main (int argc, char **argv)
switch (c)
{
case 'a':
- {
- unsigned long tmp;
- if (xstrtoul (optarg, NULL, 10, &tmp, "") != LONGINT_OK
- || SIZE_MAX / sizeof (size_t) < tmp)
- {
- error (0, 0, _("%s: invalid suffix length"), optarg);
- usage (EXIT_FAILURE);
- }
- suffix_length = tmp;
- }
+ suffix_length = xdectoumax (optarg, 0, SIZE_MAX / sizeof (size_t),
+ "", _("invalid suffix length"), 0);
break;
case ADDITIONAL_SUFFIX_OPTION:
@@ -1188,46 +1274,27 @@ main (int argc, char **argv)
if (split_type != type_undef)
FAIL_ONLY_ONE_WAY ();
split_type = type_bytes;
- if (xstrtoumax (optarg, NULL, 10, &n_units, multipliers) != LONGINT_OK
- || n_units == 0)
- {
- error (0, 0, _("%s: invalid number of bytes"), optarg);
- usage (EXIT_FAILURE);
- }
- /* If input is a pipe, we could get more data than is possible
- to write to a single file, so indicate that immediately
- rather than having possibly future invocations fail. */
- if (OFF_T_MAX < n_units)
- error (EXIT_FAILURE, EFBIG,
- _("%s: invalid number of bytes"), optarg);
-
+ /* Limit to OFF_T_MAX, becaue if input is a pipe, we could get more
+ data than is possible to write to a single file, so indicate that
+ immediately rather than having possibly future invocations fail. */
+ n_units = xdectoumax (optarg, 1, OFF_T_MAX, multipliers,
+ _("invalid number of bytes"), 0);
break;
case 'l':
if (split_type != type_undef)
FAIL_ONLY_ONE_WAY ();
split_type = type_lines;
- if (xstrtoumax (optarg, NULL, 10, &n_units, "") != LONGINT_OK
- || n_units == 0)
- {
- error (0, 0, _("%s: invalid number of lines"), optarg);
- usage (EXIT_FAILURE);
- }
+ n_units = xdectoumax (optarg, 1, UINTMAX_MAX, "",
+ _("invalid number of lines"), 0);
break;
case 'C':
if (split_type != type_undef)
FAIL_ONLY_ONE_WAY ();
split_type = type_byteslines;
- if (xstrtoumax (optarg, NULL, 10, &n_units, multipliers) != LONGINT_OK
- || n_units == 0 || SIZE_MAX < n_units)
- {
- error (0, 0, _("%s: invalid number of bytes"), optarg);
- usage (EXIT_FAILURE);
- }
- if (OFF_T_MAX < n_units)
- error (EXIT_FAILURE, EFBIG,
- _("%s: invalid number of bytes"), optarg);
+ n_units = xdectoumax (optarg, 1, MIN (SIZE_MAX, OFF_T_MAX),
+ multipliers, _("invalid number of bytes"), 0);
break;
case 'n':
@@ -1250,15 +1317,45 @@ main (int argc, char **argv)
split_type = type_chunk_bytes;
if ((slash = strchr (optarg, '/')))
parse_chunk (&k_units, &n_units, slash);
- else if (xstrtoumax (optarg, NULL, 10, &n_units, "") != LONGINT_OK
- || n_units == 0)
- error (EXIT_FAILURE, 0, _("%s: invalid number of chunks"), optarg);
+ else
+ n_units = xdectoumax (optarg, 1, UINTMAX_MAX, "",
+ _("invalid number of chunks"), 0);
break;
case 'u':
unbuffered = true;
break;
+ case 't':
+ {
+ char neweol = optarg[0];
+ if (! neweol)
+ error (EXIT_FAILURE, 0, _("empty record separator"));
+ if (optarg[1])
+ {
+ if (STREQ (optarg, "\\0"))
+ neweol = '\0';
+ else
+ {
+ /* Provoke with 'split -txx'. Complain about
+ "multi-character tab" instead of "multibyte tab", so
+ that the diagnostic's wording does not need to be
+ changed once multibyte characters are supported. */
+ error (EXIT_FAILURE, 0, _("multi-character separator %s"),
+ quote (optarg));
+ }
+ }
+ /* Make it explicit we don't support multiple separators. */
+ if (0 <= eolchar && neweol != eolchar)
+ {
+ error (EXIT_FAILURE, 0,
+ _("multiple separator characters specified"));
+ }
+
+ eolchar = neweol;
+ }
+ break;
+
case '0':
case '1':
case '2':
@@ -1318,15 +1415,8 @@ main (int argc, char **argv)
break;
case IO_BLKSIZE_OPTION:
- {
- uintmax_t tmp_blk_size;
- if (xstrtoumax (optarg, NULL, 10, &tmp_blk_size,
- multipliers) != LONGINT_OK
- || tmp_blk_size == 0 || SIZE_MAX - page_size < tmp_blk_size)
- error (0, 0, _("%s: invalid IO block size"), optarg);
- else
- in_blk_size = tmp_blk_size;
- }
+ in_blk_size = xdectoumax (optarg, 1, SIZE_MAX - page_size,
+ multipliers, _("invalid IO block size"), 0);
break;
case VERBOSE_OPTION:
@@ -1357,10 +1447,13 @@ main (int argc, char **argv)
if (n_units == 0)
{
- error (0, 0, _("%s: invalid number of lines"), "0");
+ error (0, 0, "%s: %s", _("invalid number of lines"), quote ("0"));
usage (EXIT_FAILURE);
}
+ if (eolchar < 0)
+ eolchar = '\n';
+
set_suffix_length (n_units, split_type);
/* Get out the filename arguments. */
@@ -1400,40 +1493,53 @@ main (int argc, char **argv)
if (fstat (STDIN_FILENO, &in_stat_buf) != 0)
error (EXIT_FAILURE, errno, "%s", infile);
- if (in_blk_size == 0)
+
+ bool specified_buf_size = !! in_blk_size;
+ if (! specified_buf_size)
in_blk_size = io_blksize (in_stat_buf);
+ void *b = xmalloc (in_blk_size + 1 + page_size - 1);
+ char *buf = ptr_align (b, page_size);
+ size_t initial_read = SIZE_MAX;
+
if (split_type == type_chunk_bytes || split_type == type_chunk_lines)
{
off_t input_offset = lseek (STDIN_FILENO, 0, SEEK_CUR);
- if (usable_st_size (&in_stat_buf))
- file_size = in_stat_buf.st_size;
- else if (0 <= input_offset)
+ if (0 <= input_offset)
{
- file_size = lseek (STDIN_FILENO, 0, SEEK_END);
- input_offset = (file_size < 0
- ? file_size
- : lseek (STDIN_FILENO, input_offset, SEEK_SET));
+ if (usable_st_size (&in_stat_buf) && ! specified_buf_size)
+ {
+ assert (ST_BLKSIZE (in_stat_buf) <= in_blk_size);
+ file_size = input_file_size (STDIN_FILENO, in_stat_buf.st_size,
+ buf, in_blk_size);
+ if (file_size < in_blk_size)
+ initial_read = file_size;
+ }
+ else
+ {
+ file_size = lseek (STDIN_FILENO, 0, SEEK_END);
+ input_offset = (file_size < 0
+ ? file_size
+ : lseek (STDIN_FILENO, input_offset, SEEK_SET));
+ file_size -= input_offset;
+ }
}
if (input_offset < 0)
error (EXIT_FAILURE, 0, _("%s: cannot determine file size"),
quote (infile));
- file_size -= input_offset;
/* Overflow, and sanity checking. */
if (OFF_T_MAX < n_units)
{
char buffer[INT_BUFSIZE_BOUND (uintmax_t)];
- error (EXIT_FAILURE, EFBIG, _("%s: invalid number of chunks"),
- umaxtostr (n_units, buffer));
+ error (EXIT_FAILURE, EOVERFLOW, "%s: %s",
+ _("invalid number of chunks"),
+ quote (umaxtostr (n_units, buffer)));
}
/* increase file_size to n_units here, so that we still process
any input data, and create empty files for the rest. */
file_size = MAX (file_size, n_units);
}
- void *b = xmalloc (in_blk_size + 1 + page_size - 1);
- char *buf = ptr_align (b, page_size);
-
/* When filtering, closure of one pipe must not terminate the process,
as there may still be other streams expecting input from us. */
if (filter_command)
@@ -1454,7 +1560,7 @@ main (int argc, char **argv)
break;
case type_bytes:
- bytes_split (n_units, buf, in_blk_size, 0);
+ bytes_split (n_units, buf, in_blk_size, SIZE_MAX, 0);
break;
case type_byteslines:
@@ -1463,13 +1569,16 @@ main (int argc, char **argv)
case type_chunk_bytes:
if (k_units == 0)
- bytes_split (file_size / n_units, buf, in_blk_size, n_units);
+ bytes_split (file_size / n_units, buf, in_blk_size, initial_read,
+ n_units);
else
- bytes_chunk_extract (k_units, n_units, buf, in_blk_size, file_size);
+ bytes_chunk_extract (k_units, n_units, buf, in_blk_size, initial_read,
+ file_size);
break;
case type_chunk_lines:
- lines_chunk_split (k_units, n_units, buf, in_blk_size, file_size);
+ lines_chunk_split (k_units, n_units, buf, in_blk_size, initial_read,
+ file_size);
break;
case type_rr:
@@ -1488,5 +1597,5 @@ main (int argc, char **argv)
error (EXIT_FAILURE, errno, "%s", infile);
closeout (NULL, output_desc, filter_pid, outfile);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/stat.c b/src/stat.c
index b65dbe55..6d236653 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -1,5 +1,5 @@
/* stat.c -- display file or file system status
- Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Copyright (C) 2001-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -74,15 +74,16 @@
#include "xvasprintf.h"
#if USE_STATVFS
-# define STRUCT_STATVFS struct statvfs
# define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATVFS_F_FSID_IS_INTEGER
# define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS_F_TYPE
# if HAVE_STRUCT_STATVFS_F_NAMEMAX
# define SB_F_NAMEMAX(S) ((S)->f_namemax)
# endif
# if ! STAT_STATVFS && STAT_STATVFS64
+# define STRUCT_STATVFS struct statvfs64
# define STATFS statvfs64
# else
+# define STRUCT_STATVFS struct statvfs
# define STATFS statvfs
# endif
# define STATFS_FRSIZE(S) ((S)->f_frsize)
@@ -336,6 +337,8 @@ human_fstype (STRUCT_STATVFS const *statfsbuf)
return "hugetlbfs";
case S_MAGIC_MTD_INODE_FS: /* 0x11307854 local */
return "inodefs";
+ case S_MAGIC_IBRIX: /* 0x013111A8 remote */
+ return "ibrix";
case S_MAGIC_INOTIFYFS: /* 0x2BAD1DEA local */
return "inotifyfs";
case S_MAGIC_ISOFS: /* 0x9660 local */
@@ -1491,7 +1494,7 @@ Valid format sequences for file systems:\n\
%T file system type in human readable form\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -1575,5 +1578,5 @@ main (int argc, char *argv[])
? do_statfs (argv[i], format)
: do_stat (argv[i], format, format2));
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/stdbuf.c b/src/stdbuf.c
index 92ee2826..116619d7 100644
--- a/src/stdbuf.c
+++ b/src/stdbuf.c
@@ -1,5 +1,5 @@
/* stdbuf -- setup the standard streams for a command
- Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Copyright (C) 2009-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -66,7 +66,7 @@ parse_size (char const *str, size_t *size)
{
uintmax_t tmp_size;
enum strtol_error e = xstrtoumax (str, NULL, 10, &tmp_size, "EGkKMPTYZ0");
- if (e == LONGINT_OK && tmp_size > SIZE_MAX)
+ if (e == LONGINT_OK && SIZE_MAX < tmp_size)
e = LONGINT_OVERFLOW;
if (e == LONGINT_OK)
@@ -76,7 +76,7 @@ parse_size (char const *str, size_t *size)
return 0;
}
- errno = (e == LONGINT_OVERFLOW ? EOVERFLOW : 0);
+ errno = (e == LONGINT_OVERFLOW ? EOVERFLOW : errno);
return -1;
}
@@ -115,11 +115,11 @@ size set to MODE bytes.\n\
"), stdout);
fputs (_("\n\
NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does\n\
-for e.g.) then that will override corresponding settings changed by 'stdbuf'.\n\
+for example) then that will override corresponding changes by 'stdbuf'.\n\
Also some filters (like 'dd' and 'cat' etc.) don't use streams for I/O,\n\
and are thus unaffected by 'stdbuf' settings.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -256,7 +256,7 @@ set_LD_PRELOAD (void)
ret = putenv (LD_PRELOAD);
#ifdef __APPLE__
if (ret == 0)
- ret = putenv ("DYLD_FORCE_FLAT_NAMESPACE=y");
+ ret = setenv ("DYLD_FORCE_FLAT_NAMESPACE", "y", 1);
#endif
if (ret != 0)
@@ -387,9 +387,7 @@ main (int argc, char **argv)
execvp (*argv, argv);
- {
- int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
- error (0, errno, _("failed to run command %s"), quote (argv[0]));
- exit (exit_status);
- }
+ int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
+ error (0, errno, _("failed to run command %s"), quote (argv[0]));
+ return exit_status;
}
diff --git a/src/stty.c b/src/stty.c
index 3c485786..c0057f2d 100644
--- a/src/stty.c
+++ b/src/stty.c
@@ -1,5 +1,5 @@
/* stty -- change and print terminal line settings
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -58,6 +58,7 @@
#include "error.h"
#include "fd-reopen.h"
#include "quote.h"
+#include "xdectoint.h"
#include "xstrtol.h"
/* The official name of this program (e.g., no 'g' prefix). */
@@ -190,6 +191,7 @@ enum mode_type
#define SANE_UNSET 2 /* Unset in 'sane' mode. */
#define REV 4 /* Can be turned off by prepending '-'. */
#define OMIT 8 /* Don't display value. */
+#define NO_SETATTR 16 /* tcsetattr not used to set mode bits. */
/* Each mode. */
struct mode_info
@@ -341,6 +343,11 @@ static struct mode_info const mode_info[] =
{"echoke", local, SANE_SET | REV, ECHOKE, 0},
{"crtkill", local, REV | OMIT, ECHOKE, 0},
#endif
+#if defined TIOCEXT
+ {"extproc", local, SANE_UNSET | REV | NO_SETATTR, EXTPROC, 0},
+#elif defined EXTPROC
+ {"extproc", local, SANE_UNSET | REV, EXTPROC, 0},
+#endif
{"evenp", combination, REV | OMIT, 0, 0},
{"parity", combination, REV | OMIT, 0, 0},
@@ -413,7 +420,8 @@ static struct control_info const control_info[] =
{"lnext", CLNEXT, VLNEXT},
#endif
#ifdef VFLUSHO
- {"flush", CFLUSHO, VFLUSHO},
+ {"flush", CFLUSHO, VFLUSHO}, /* deprecated compat option. */
+ {"discard", CFLUSHO, VFLUSHO},
#endif
#ifdef VSTATUS
{"status", CSTATUS, VSTATUS},
@@ -539,45 +547,94 @@ settings. The underlying system defines which settings are available.\n\
"), stdout);
fputs (_("\
\n\
-Special characters:\n\
+Special characters:\n"), stdout);
+#ifdef VFLUSHO
+ fputs (_("\
+ * discard CHAR CHAR will toggle discarding of output\n\
+"), stdout);
+#endif
+#ifdef VDSUSP
+ fputs (_("\
* dsusp CHAR CHAR will send a terminal stop signal once input flushed\n\
+"), stdout);
+#endif
+ fputs (_("\
eof CHAR CHAR will send an end of file (terminate the input)\n\
eol CHAR CHAR will end the line\n\
"), stdout);
+#ifdef VEOL2
fputs (_("\
* eol2 CHAR alternate CHAR for ending the line\n\
+"), stdout);
+#endif
+ fputs (_("\
erase CHAR CHAR will erase the last character typed\n\
intr CHAR CHAR will send an interrupt signal\n\
kill CHAR CHAR will erase the current line\n\
"), stdout);
+#ifdef VLNEXT
fputs (_("\
* lnext CHAR CHAR will enter the next character quoted\n\
+"), stdout);
+#endif
+#ifdef VSTATUS
+ fputs (_("\
+ * status CHAR CHAR will send an info signal\n\
+"), stdout);
+#endif
+ fputs (_("\
quit CHAR CHAR will send a quit signal\n\
+"), stdout);
+#if defined CREPRINT || defined VREPRINT
+ fputs (_("\
* rprnt CHAR CHAR will redraw the current line\n\
- start CHAR CHAR will restart the output after stopping it\n\
"), stdout);
+#endif
fputs (_("\
+ start CHAR CHAR will restart the output after stopping it\n\
stop CHAR CHAR will stop the output\n\
susp CHAR CHAR will send a terminal stop signal\n\
+"), stdout);
+#ifdef VSWTCH
+ fputs (_("\
* swtch CHAR CHAR will switch to a different shell layer\n\
+"), stdout);
+#endif
+#ifdef VWERASE
+ fputs (_("\
* werase CHAR CHAR will erase the last word typed\n\
"), stdout);
+#endif
fputs (_("\
\n\
Special settings:\n\
N set the input and output speeds to N bauds\n\
+"), stdout);
+#ifdef TIOCGWINSZ
+ fputs (_("\
* cols N tell the kernel that the terminal has N columns\n\
* columns N same as cols N\n\
"), stdout);
+#endif
fputs (_("\
ispeed N set the input speed to N\n\
+"), stdout);
+#ifdef HAVE_C_LINE
+ fputs (_("\
* line N use line discipline N\n\
+"), stdout);
+#endif
+ fputs (_("\
min N with -icanon, set N characters minimum for a completed read\n\
ospeed N set the output speed to N\n\
"), stdout);
+#ifdef TIOCGWINSZ
fputs (_("\
* rows N tell the kernel that the terminal has N rows\n\
* size print the number of rows and columns according to the kernel\n\
+"), stdout);
+#endif
+ fputs (_("\
speed print the terminal speed\n\
time N with -icanon, set read timeout of N tenths of a second\n\
"), stdout);
@@ -586,8 +643,18 @@ Special settings:\n\
Control settings:\n\
[-]clocal disable modem control signals\n\
[-]cread allow input to be received\n\
+"), stdout);
+#ifdef CRTSCTS
+ fputs (_("\
* [-]crtscts enable RTS/CTS handshaking\n\
+"), stdout);
+#endif
+#ifdef CDTRDSR
+ fputs (_("\
* [-]cdtrdsr enable DTR/DSR handshaking\n\
+"), stdout);
+#endif
+ fputs (_("\
csN set character size to N bits, N in [5..8]\n\
"), stdout);
fputs (_("\
@@ -596,8 +663,12 @@ Control settings:\n\
[-]hupcl same as [-]hup\n\
[-]parenb generate parity bit in output and expect parity bit in input\n\
[-]parodd set odd parity (or even parity with '-')\n\
+"), stdout);
+#ifdef CMSPAR
+ fputs (_("\
* [-]cmspar use \"stick\" (mark/space) parity\n\
"), stdout);
+#endif
fputs (_("\
\n\
Input settings:\n\
@@ -605,20 +676,34 @@ Input settings:\n\
[-]icrnl translate carriage return to newline\n\
[-]ignbrk ignore break characters\n\
[-]igncr ignore carriage return\n\
+ [-]ignpar ignore characters with parity errors\n\
"), stdout);
+#ifdef IMAXBEL
fputs (_("\
- [-]ignpar ignore characters with parity errors\n\
* [-]imaxbel beep and do not flush a full input buffer on a character\n\
+"), stdout);
+#endif
+ fputs (_("\
[-]inlcr translate newline to carriage return\n\
[-]inpck enable input parity checking\n\
[-]istrip clear high (8th) bit of input characters\n\
"), stdout);
+#ifdef IUTF8
fputs (_("\
* [-]iutf8 assume input characters are UTF-8 encoded\n\
"), stdout);
+#endif
+#ifdef IUCLC
fputs (_("\
* [-]iuclc translate uppercase characters to lowercase\n\
+"), stdout);
+#endif
+#ifdef IXANY
+ fputs (_("\
* [-]ixany let any character restart output, not only start character\n\
+"), stdout);
+#endif
+ fputs (_("\
[-]ixoff enable sending of start/stop characters\n\
[-]ixon enable XON/XOFF flow control\n\
[-]parmrk mark parity errors (with a 255-0-character sequence)\n\
@@ -627,59 +712,163 @@ Input settings:\n\
fputs (_("\
\n\
Output settings:\n\
+"), stdout);
+#ifdef BSDLY
+ fputs (_("\
* bsN backspace delay style, N in [0..1]\n\
+"), stdout);
+#endif
+#ifdef CRDLY
+ fputs (_("\
* crN carriage return delay style, N in [0..3]\n\
+"), stdout);
+#endif
+#ifdef FFDLY
+ fputs (_("\
* ffN form feed delay style, N in [0..1]\n\
+"), stdout);
+#endif
+#ifdef NLDLY
+ fputs (_("\
* nlN newline delay style, N in [0..1]\n\
"), stdout);
+#endif
+#ifdef OCRNL
fputs (_("\
* [-]ocrnl translate carriage return to newline\n\
+"), stdout);
+#endif
+#ifdef OFDEL
+ fputs (_("\
* [-]ofdel use delete characters for fill instead of NUL characters\n\
+"), stdout);
+#endif
+#ifdef OFILL
+ fputs (_("\
* [-]ofill use fill (padding) characters instead of timing for delays\n\
+"), stdout);
+#endif
+#ifdef OLCUC
+ fputs (_("\
* [-]olcuc translate lowercase characters to uppercase\n\
+"), stdout);
+#endif
+#ifdef ONLCR
+ fputs (_("\
* [-]onlcr translate newline to carriage return-newline\n\
+"), stdout);
+#endif
+#ifdef ONLRET
+ fputs (_("\
* [-]onlret newline performs a carriage return\n\
"), stdout);
+#endif
+#ifdef ONOCR
fputs (_("\
* [-]onocr do not print carriage returns in the first column\n\
+"), stdout);
+#endif
+ fputs (_("\
[-]opost postprocess output\n\
+"), stdout);
+#if defined TABDLY || defined OXTABS
+ fputs (_("\
* tabN horizontal tab delay style, N in [0..3]\n\
* tabs same as tab0\n\
* -tabs same as tab3\n\
+"), stdout);
+#endif
+#ifdef VTDLY
+ fputs (_("\
* vtN vertical tab delay style, N in [0..1]\n\
"), stdout);
+#endif
fputs (_("\
\n\
Local settings:\n\
[-]crterase echo erase characters as backspace-space-backspace\n\
+"), stdout);
+#ifdef ECHOKE
+ fputs (_("\
* crtkill kill all line by obeying the echoprt and echoe settings\n\
* -crtkill kill all line by obeying the echoctl and echok settings\n\
"), stdout);
+#endif
+#ifdef ECHOCTL
fputs (_("\
* [-]ctlecho echo control characters in hat notation ('^c')\n\
+"), stdout);
+#endif
+ fputs (_("\
[-]echo echo input characters\n\
+"), stdout);
+#ifdef ECHOCTL
+ fputs (_("\
* [-]echoctl same as [-]ctlecho\n\
+"), stdout);
+#endif
+ fputs (_("\
[-]echoe same as [-]crterase\n\
[-]echok echo a newline after a kill character\n\
"), stdout);
+#ifdef ECHOKE
fputs (_("\
* [-]echoke same as [-]crtkill\n\
+"), stdout);
+#endif
+ fputs (_("\
[-]echonl echo newline even if not echoing other characters\n\
+"), stdout);
+#ifdef ECHOPRT
+ fputs (_("\
* [-]echoprt echo erased characters backward, between '\\' and '/'\n\
- [-]icanon enable erase, kill, werase, and rprnt special characters\n\
- [-]iexten enable non-POSIX special characters\n\
"), stdout);
+#endif
+#if defined EXTPROC || defined TIOCEXT
+ fputs (_("\
+ * [-]extproc enable \"LINEMODE\"; useful with high latency links\n\
+"), stdout);
+#endif
+ printf (_("\
+ [-]icanon enable special characters: %s\n\
+ [-]iexten enable non-POSIX special characters\n\
+"), "erase, kill"
+#ifdef VWERASE
+ ", werase"
+#endif
+#if defined CREPRINT || defined VREPRINT
+ ", rprnt"
+#endif
+);
fputs (_("\
[-]isig enable interrupt, quit, and suspend special characters\n\
[-]noflsh disable flushing after interrupt and quit special characters\n\
+"), stdout);
+#ifdef ECHOPRT
+ fputs (_("\
* [-]prterase same as [-]echoprt\n\
+"), stdout);
+#endif
+#ifdef TOSTOP
+ fputs (_("\
* [-]tostop stop background jobs that try to write to the terminal\n\
+"), stdout);
+#endif
+#ifdef XCASE
+ fputs (_("\
* [-]xcase with icanon, escape with '\\' for uppercase characters\n\
"), stdout);
+#endif
fputs (_("\
\n\
Combination settings:\n\
+"), stdout);
+#if defined XCASE && defined IUCLC && defined OLCUC
+ fputs (_("\
* [-]LCASE same as [-]lcase\n\
+"), stdout);
+#endif
+ fputs (_("\
cbreak same as -icanon\n\
-cbreak same as icanon\n\
"), stdout);
@@ -687,22 +876,69 @@ Combination settings:\n\
cooked same as brkint ignpar istrip icrnl ixon opost isig\n\
icanon, eof and eol characters to their default values\n\
-cooked same as raw\n\
- crt same as echoe echoctl echoke\n\
"), stdout);
- fputs (_("\
- dec same as echoe echoctl echoke -ixany intr ^c erase 0177\n\
+ printf (_("\
+ crt same as %s\n\
+"), "echoe"
+#ifdef ECHOCTL
+ " echoctl"
+#endif
+#ifdef ECHOKE
+ " echoke"
+#endif
+);
+ printf (_("\
+ dec same as %s intr ^c erase 0177\n\
kill ^u\n\
+"), "echoe"
+#ifdef ECHOCTL
+ " echoctl"
+#endif
+#ifdef ECHOKE
+ " echoke"
+#endif
+#ifdef IXANY
+ " -ixany"
+#endif
+);
+#ifdef IXANY
+ fputs (_("\
* [-]decctlq same as [-]ixany\n\
+"), stdout);
+#endif
+ fputs (_("\
ek erase and kill characters to their default values\n\
evenp same as parenb -parodd cs7\n\
+ -evenp same as -parenb cs8\n\
"), stdout);
+#if defined XCASE && defined IUCLC && defined OLCUC
fputs (_("\
- -evenp same as -parenb cs8\n\
* [-]lcase same as xcase iuclc olcuc\n\
+"), stdout);
+#endif
+ fputs (_("\
litout same as -parenb -istrip -opost cs8\n\
-litout same as parenb istrip opost cs7\n\
- nl same as -icrnl -onlcr\n\
- -nl same as icrnl -inlcr -igncr onlcr -ocrnl -onlret\n\
+"), stdout);
+ printf (_("\
+ nl same as %s\n\
+ -nl same as %s\n\
+"), "-icrnl"
+#ifdef ONLCR
+ " -onlcr"
+#endif
+ , "icrnl -inlcr -igncr"
+#ifdef ONLCR
+ " onlcr"
+#endif
+#ifdef OCRNL
+ " -ocrnl"
+#endif
+#ifdef ONLRET
+ " -onlret"
+#endif
+);
+ fputs (_("\
"), stdout);
fputs (_("\
oddp same as parenb parodd cs7\n\
@@ -711,20 +947,108 @@ Combination settings:\n\
pass8 same as -parenb -istrip cs8\n\
-pass8 same as parenb istrip cs7\n\
"), stdout);
- fputs (_("\
+ printf (_("\
raw same as -ignbrk -brkint -ignpar -parmrk -inpck -istrip\n\
- -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany\n\
- -imaxbel -opost -isig -icanon -xcase min 1 time 0\n\
+ -inlcr -igncr -icrnl -ixon -ixoff -icanon -opost\n\
+ -isig%s min 1 time 0\n\
-raw same as cooked\n\
-"), stdout);
- fputs (_("\
- sane same as cread -ignbrk brkint -inlcr -igncr icrnl -iutf8\n\
- -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr\n\
- -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0\n\
- isig icanon iexten echo echoe echok -echonl -noflsh\n\
- -xcase -tostop -echoprt echoctl echoke, all special\n\
- characters to their default values\n\
-"), stdout);
+"),
+#ifdef IUCLC
+ " -iuclc"
+#endif
+#ifdef IXANY
+ " -ixany"
+#endif
+#ifdef IMAXBEL
+ " -imaxbel"
+#endif
+#ifdef XCASE
+ " -xcase"
+#endif
+);
+ printf (_("\
+ sane same as cread -ignbrk brkint -inlcr -igncr icrnl\n\
+ icanon iexten echo echoe echok -echonl -noflsh\n\
+ %s\n\
+ %s\n\
+ %s,\n\
+ all special characters to their default values\n\
+"),
+ "-ixoff"
+#ifdef IUTF8
+ " -iutf8"
+#endif
+#ifdef IUCLC
+ " -iuclc"
+#endif
+#ifdef IXANY
+ " -ixany"
+#endif
+#ifdef IMAXBEL
+ " imaxbel"
+#endif
+#ifdef XCASE
+ " -xcase"
+#endif
+#ifdef OLCUC
+ " -olcuc"
+#endif
+#ifdef OCRNL
+ " -ocrnl"
+#endif
+
+ , "opost"
+#ifdef OFILL
+ " -ofill"
+#endif
+#ifdef ONLCR
+ " onlcr"
+#endif
+#ifdef ONOCR
+ " -onocr"
+#endif
+#ifdef ONLRET
+ " -onlret"
+#endif
+#ifdef NLDLY
+ " nl0"
+#endif
+#ifdef CRDLY
+ " cr0"
+#endif
+#ifdef TAB0
+ " tab0"
+#endif
+#ifdef BSDLY
+ " bs0"
+#endif
+#ifdef VTDLY
+ " vt0"
+#endif
+#ifdef FFDLY
+ " ff0"
+#endif
+
+ , "isig"
+#ifdef TOSTOP
+ " -tostop"
+#endif
+#ifdef OFDEL
+ " -ofdel"
+#endif
+#ifdef ECHOPRT
+ " -echoprt"
+#endif
+#ifdef ECHOCTL
+ " echoctl"
+#endif
+#ifdef ECHOKE
+ " echoke"
+#endif
+#ifdef EXTPROC
+ " -extproc"
+#endif
+);
fputs (_("\
\n\
Handle the tty line connected to standard input. Without arguments,\n\
@@ -732,7 +1056,7 @@ prints baud rate, line discipline, and deviations from stty sane. In\n\
settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
127; special values ^- or undef used to disable special characters.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -862,7 +1186,7 @@ main (int argc, char **argv)
max_col = screen_columns ();
current_col = 0;
display_settings (output_type, &mode, device_name);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
speed_was_set = false;
@@ -871,6 +1195,7 @@ main (int argc, char **argv)
{
char const *arg = argv[k];
bool match_found = false;
+ bool not_set_attr = false;
bool reversed = false;
int i;
@@ -886,8 +1211,13 @@ main (int argc, char **argv)
{
if (STREQ (arg, mode_info[i].name))
{
- match_found = set_mode (&mode_info[i], reversed, &mode);
- require_set_attr = true;
+ if ((mode_info[i].flags & NO_SETATTR) == 0)
+ {
+ match_found = set_mode (&mode_info[i], reversed, &mode);
+ require_set_attr = true;
+ }
+ else
+ match_found = not_set_attr = true;
break;
}
}
@@ -915,7 +1245,7 @@ main (int argc, char **argv)
}
}
}
- if (!match_found)
+ if (!match_found || not_set_attr)
{
if (STREQ (arg, "ispeed"))
{
@@ -941,6 +1271,20 @@ main (int argc, char **argv)
speed_was_set = true;
require_set_attr = true;
}
+#ifdef TIOCEXT
+ /* This is the BSD interface to "extproc".
+ Even though it's an lflag, an ioctl is used to set it. */
+ else if (STREQ (arg, "extproc"))
+ {
+ int val = ! reversed;
+
+ if (ioctl (STDIN_FILENO, TIOCEXT, &val) != 0)
+ {
+ error (EXIT_FAILURE, errno, _("%s: error setting %s"),
+ device_name, quote (arg));
+ }
+ }
+#endif
#ifdef TIOCGWINSZ
else if (STREQ (arg, "rows"))
{
@@ -1070,7 +1414,7 @@ main (int argc, char **argv)
}
}
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
/* Return false if not applied because not reversible; otherwise
@@ -1506,6 +1850,12 @@ display_changed (struct termios *mode)
{
if (mode->c_cc[control_info[i].offset] == control_info[i].saneval)
continue;
+
+#ifdef VFLUSHO
+ /* 'flush' is the deprecated equivalent of 'discard'. */
+ if (STREQ (control_info[i].name, "flush"))
+ continue;
+#endif
/* If swtch is the same as susp, don't print both. */
#if VSWTCH == VSUSP
if (STREQ (control_info[i].name, "swtch"))
@@ -1596,6 +1946,11 @@ display_all (struct termios *mode, char const *device_name)
for (i = 0; ! STREQ (control_info[i].name, "min"); ++i)
{
+#ifdef VFLUSHO
+ /* 'flush' is the deprecated equivalent of 'discard'. */
+ if (STREQ (control_info[i].name, "flush"))
+ continue;
+#endif
/* If swtch is the same as susp, don't print both. */
#if VSWTCH == VSUSP
if (STREQ (control_info[i].name, "swtch"))
@@ -1847,6 +2202,9 @@ sane_mode (struct termios *mode)
for (i = 0; mode_info[i].name != NULL; ++i)
{
+ if (mode_info[i].flags & NO_SETATTR)
+ continue;
+
if (mode_info[i].flags & SANE_SET)
{
bitsp = mode_type_flag (mode_info[i].type, mode);
@@ -1918,11 +2276,5 @@ visible (cc_t ch)
static unsigned long int
integer_arg (const char *s, unsigned long int maxval)
{
- unsigned long int value;
- if (xstrtoul (s, NULL, 0, &value, "bB") != LONGINT_OK || maxval < value)
- {
- error (0, 0, _("invalid integer argument %s"), quote (s));
- usage (EXIT_FAILURE);
- }
- return value;
+ return xnumtoumax (s, 0, 0, maxval, "bB", _("invalid integer argument"), 0);
}
diff --git a/src/sum.c b/src/sum.c
index 442b7ad8..51956c61 100644
--- a/src/sum.c
+++ b/src/sum.c
@@ -1,5 +1,5 @@
/* sum -- checksum and count the blocks in a file
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -61,17 +61,18 @@ Usage: %s [OPTION]... [FILE]...\n\
program_name);
fputs (_("\
Print checksum and block counts for each FILE.\n\
+"), stdout);
+
+ emit_stdin_note ();
+
+ fputs (_("\
\n\
-r use BSD sum algorithm, use 1K blocks\n\
-s, --sysv use System V sum algorithm, use 512 bytes blocks\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
-With no FILE, or when FILE is -, read standard input.\n\
-"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -270,5 +271,5 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, "-");
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/sync.c b/src/sync.c
index 8c890432..5e1dbb8c 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -1,5 +1,5 @@
/* sync - update the super block
- Copyright (C) 1994-2014 Free Software Foundation, Inc.
+ Copyright (C) 1994-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,18 +17,42 @@
/* Written by Jim Meyering */
#include <config.h>
+#include <assert.h>
#include <getopt.h>
#include <stdio.h>
#include <sys/types.h>
#include "system.h"
#include "error.h"
-#include "long-options.h"
+#include "quote.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "sync"
-#define AUTHORS proper_name ("Jim Meyering")
+#define AUTHORS \
+ proper_name ("Jim Meyering"), \
+ proper_name ("Giuseppe Scrivano")
+
+#ifndef HAVE_SYNCFS
+# define HAVE_SYNCFS 0
+#endif
+
+enum sync_mode
+{
+ MODE_FILE,
+ MODE_DATA,
+ MODE_FILE_SYSTEM,
+ MODE_SYNC
+};
+
+static struct option const long_options[] =
+{
+ {"data", no_argument, NULL, 'd'},
+ {"file-system", no_argument, NULL, 'f'},
+ {GETOPT_HELP_OPTION_DECL},
+ {GETOPT_VERSION_OPTION_DECL},
+ {NULL, 0, NULL, 0}
+};
void
usage (int status)
@@ -37,21 +61,119 @@ usage (int status)
emit_try_help ();
else
{
- printf (_("Usage: %s [OPTION]\n"), program_name);
+ printf (_("Usage: %s [OPTION] [FILE]...\n"), program_name);
fputs (_("\
-Force changed blocks to disk, update the super block.\n\
+Synchronize cached writes to persistent storage\n\
+\n\
+If one or more files are specified, sync only them,\n\
+or their containing file systems.\n\
\n\
"), stdout);
+
+ fputs (_("\
+ -d, --data sync only file data, no unneeded metadata\n\
+"), stdout);
+ fputs (_("\
+ -f, --file-system sync the file systems that contain the files\n\
+"), stdout);
+
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
+/* Sync the specified FILE, or file systems associated with FILE.
+ Return 1 on success. */
+
+static bool
+sync_arg (enum sync_mode mode, char const *file)
+{
+ bool ret = true;
+ int open_flags = O_RDONLY | O_NONBLOCK;
+ int fd;
+
+#ifdef _AIX
+ /* AIX 7.1 fsync requires write access to file. */
+ if (mode == MODE_FILE)
+ open_flags = O_WRONLY | O_NONBLOCK;
+#endif
+
+ /* Note O_PATH might be supported with syncfs(),
+ though as of Linux 3.18 is not. */
+ fd = open (file, open_flags);
+ if (fd < 0)
+ {
+ /* Use the O_RDONLY errno, which is significant
+ with directories for example. */
+ int rd_errno = errno;
+ if (open_flags != (O_WRONLY | O_NONBLOCK))
+ fd = open (file, O_WRONLY | O_NONBLOCK);
+ if (fd < 0)
+ error (0, rd_errno, _("error opening %s"), quote (file));
+ return false;
+ }
+
+ /* We used O_NONBLOCK above to not hang with fifos,
+ so reset that here. */
+ int fdflags = fcntl (fd, F_GETFL);
+ if (fdflags == -1
+ || fcntl (fd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
+ {
+ error (0, errno, _("couldn't reset non-blocking mode %s"), quote (file));
+ ret = false;
+ }
+
+ if (ret == true)
+ {
+ int sync_status = -1;
+
+ switch (mode)
+ {
+ case MODE_DATA:
+ sync_status = fdatasync (fd);
+ break;
+
+ case MODE_FILE:
+ sync_status = fsync (fd);
+ break;
+
+#if HAVE_SYNCFS
+ case MODE_FILE_SYSTEM:
+ sync_status = syncfs (fd);
+ break;
+#endif
+
+ default:
+ assert ("invalid sync_mode");
+ }
+
+ if (sync_status < 0)
+ {
+ error (0, errno, _("error syncing %s"), quote (file));
+ ret = false;
+ }
+ }
+
+ if (close (fd) < 0)
+ {
+ error (0, errno, _("failed to close %s"), quote (file));
+ ret = false;
+ }
+
+ return ret;
+}
+
int
main (int argc, char **argv)
{
+ int c;
+ bool args_specified;
+ bool arg_data = false, arg_file_system = false;
+ enum sync_mode mode;
+ bool ok = true;
+
initialize_main (&argc, &argv);
set_program_name (argv[0]);
setlocale (LC_ALL, "");
@@ -60,14 +182,55 @@ main (int argc, char **argv)
atexit (close_stdout);
- parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, Version,
- usage, AUTHORS, (char const *) NULL);
- if (getopt_long (argc, argv, "", NULL, NULL) != -1)
- usage (EXIT_FAILURE);
+ while ((c = getopt_long (argc, argv, "df", long_options, NULL))
+ != -1)
+ {
+ switch (c)
+ {
+ case 'd':
+ arg_data = true;
+ break;
+
+ case 'f':
+ arg_file_system = true;
+ break;
+
+ case_GETOPT_HELP_CHAR;
- if (optind < argc)
- error (0, 0, _("ignoring all arguments"));
+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+ default:
+ usage (EXIT_FAILURE);
+ }
+ }
+
+ args_specified = optind < argc;
+
+ if (arg_data && arg_file_system)
+ {
+ error (EXIT_FAILURE, 0,
+ _("cannot specify both --data and --file-system"));
+ }
+
+ if (!args_specified && arg_data)
+ error (EXIT_FAILURE, 0, _("--data needs at least one argument"));
+
+ if (! args_specified || (arg_file_system && ! HAVE_SYNCFS))
+ mode = MODE_SYNC;
+ else if (arg_file_system)
+ mode = MODE_FILE_SYSTEM;
+ else if (! arg_data)
+ mode = MODE_FILE;
+ else
+ mode = MODE_DATA;
+
+ if (mode == MODE_SYNC)
+ sync ();
+ else
+ {
+ for (; optind < argc; optind++)
+ ok &= sync_arg (mode, argv[optind]);
+ }
- sync ();
- exit (EXIT_SUCCESS);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/system.h b/src/system.h
index 162446c1..8f6a2ea8 100644
--- a/src/system.h
+++ b/src/system.h
@@ -1,5 +1,5 @@
/* system-dependent definitions for coreutils
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,16 +18,6 @@
#include <alloca.h>
-/* Include <sys/types.h> before this file.
- Note this doesn't warn if we're included
- before all system headers. */
-
-#if 2 < __GLIBC__ || ( 2 == ___GLIBC__ && 2 <= __GLIBC_MINOR__ )
-# if ! defined _SYS_TYPES_H
-you must include <sys/types.h> before including this file
-# endif
-#endif
-
#include <sys/stat.h>
/* Commonly used file permission combination. */
@@ -135,9 +125,14 @@ enum
#include <inttypes.h>
/* Redirection and wildcarding when done by the utility itself.
- Generally a noop, but used in particular for native VMS. */
+ Generally a noop, but used in particular for OS/2. */
#ifndef initialize_main
-# define initialize_main(ac, av)
+# ifndef __OS2__
+# define initialize_main(ac, av)
+# else
+# define initialize_main(ac, av) \
+ do { _wildcard (ac, av); _response (ac, av); } while (0)
+# endif
#endif
#include "stat-macros.h"
@@ -188,12 +183,11 @@ select_plural (uintmax_t n)
#define STREQ(a, b) (strcmp (a, b) == 0)
#define STREQ_LEN(a, b, n) (strncmp (a, b, n) == 0)
-#define STRPREFIX(a, b) (strncmp(a, b, strlen (b)) == 0)
+#define STRPREFIX(a, b) (strncmp (a, b, strlen (b)) == 0)
/* Just like strncmp, but the second argument must be a literal string
and you don't specify the length; that comes from the literal. */
-#define STRNCMP_LIT(s, literal) \
- strncmp (s, "" literal "", sizeof (literal) - 1)
+#define STRNCMP_LIT(s, lit) strncmp (s, "" lit "", sizeof (lit) - 1)
#if !HAVE_DECL_GETLOGIN
char *getlogin ();
@@ -538,6 +532,13 @@ is_nul (void const *buf, size_t bufsize)
)
static inline void
+emit_stdin_note (void)
+{
+ fputs (_("\n\
+With no FILE, or when FILE is -, read standard input.\n\
+"), stdout);
+}
+static inline void
emit_mandatory_arg_note (void)
{
fputs (_("\n\
@@ -565,9 +566,29 @@ Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set).\n\
}
static inline void
-emit_ancillary_info (void)
+emit_ancillary_info (char const *program)
{
+ struct infomap { char const *program; char const *node; } const infomap[] = {
+ { "[", "test invocation" },
+ { "coreutils", "Multi-call invocation" },
+ { "sha224sum", "sha2 utilities" },
+ { "sha256sum", "sha2 utilities" },
+ { "sha384sum", "sha2 utilities" },
+ { "sha512sum", "sha2 utilities" },
+ { NULL, NULL }
+ };
+
+ char const *node = program;
+ struct infomap const *map_prog = infomap;
+
+ while (map_prog->program && ! STREQ (program, map_prog->program))
+ map_prog++;
+
+ if (map_prog->node)
+ node = map_prog->node;
+
printf (_("\n%s online help: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
+
/* Don't output this redundant message for English locales.
Note we still output for 'C' so that it gets included in the man page. */
const char *lc_messages = setlocale (LC_MESSAGES, NULL);
@@ -578,11 +599,12 @@ emit_ancillary_info (void)
the URLs at http://translationproject.org/team/. Otherwise, replace
the entire URL with your translation team's email address. */
printf (_("Report %s translation bugs to "
- "<http://translationproject.org/team/>\n"),
- last_component (program_name));
+ "<http://translationproject.org/team/>\n"), program);
}
- printf (_("For complete documentation, run: "
- "info coreutils '%s invocation'\n"), last_component (program_name));
+ printf (_("Full documentation at: <%s%s>\n"),
+ PACKAGE_URL, program);
+ printf (_("or available locally via: info '(coreutils) %s%s'\n"),
+ node, node == program ? " invocation" : "");
}
static inline void
@@ -663,3 +685,13 @@ stzncpy (char *restrict dest, char const *restrict src, size_t len)
in selinux.h before libselinux-2.3 (May 2014).
When version >= 2.3 is ubiquitous remove this function. */
static inline char * se_const (char const * sctx) { return (char *) sctx; }
+
+/* Return true if ERR is ENOTSUP or EOPNOTSUPP, otherwise false.
+ This wrapper function avoids the redundant 'or'd comparison on
+ systems like Linux for which they have the same value. It also
+ avoids the gcc warning to that effect. */
+static inline bool
+is_ENOTSUP (int err)
+{
+ return err == EOPNOTSUPP || (ENOTSUP != EOPNOTSUPP && err == ENOTSUP);
+}
diff --git a/src/tac-pipe.c b/src/tac-pipe.c
index 8e634f3e..669a8655 100644
--- a/src/tac-pipe.c
+++ b/src/tac-pipe.c
@@ -1,6 +1,6 @@
/* tac from a pipe.
- Copyright (C) 1997-2014 Free Software Foundation, Inc.
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/tac.c b/src/tac.c
index c76afc77..57e7e761 100644
--- a/src/tac.c
+++ b/src/tac.c
@@ -1,5 +1,5 @@
/* tac - concatenate and print files in reverse
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -136,9 +136,9 @@ Usage: %s [OPTION]... [FILE]...\n\
program_name);
fputs (_("\
Write each FILE to standard output, last line first.\n\
-With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -148,7 +148,7 @@ With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -187,10 +187,11 @@ output (const char *start, const char *past_end)
}
/* Print in reverse the file open on descriptor FD for reading FILE.
+ The file is already positioned at FILE_POS, which should be near its end.
Return true if successful. */
static bool
-tac_seekable (int input_fd, const char *file)
+tac_seekable (int input_fd, const char *file, off_t file_pos)
{
/* Pointer to the location in 'G_buffer' where the search for
the next separator will begin. */
@@ -203,9 +204,6 @@ tac_seekable (int input_fd, const char *file)
/* Length of the record growing in 'G_buffer'. */
size_t saved_record_size;
- /* Offset in the file of the next read. */
- off_t file_pos;
-
/* True if 'output' has not been called yet for any file.
Only used when the separator is attached to the preceding record. */
bool first_time = true;
@@ -213,27 +211,43 @@ tac_seekable (int input_fd, const char *file)
char const *separator1 = separator + 1; /* Speed optimization, non-regexp. */
size_t match_length1 = match_length - 1; /* Speed optimization, non-regexp. */
- /* Find the size of the input file. */
- file_pos = lseek (input_fd, 0, SEEK_END);
- if (file_pos < 1)
- return true; /* It's an empty file. */
-
/* Arrange for the first read to lop off enough to leave the rest of the
file a multiple of 'read_size'. Since 'read_size' can change, this may
not always hold during the program run, but since it usually will, leave
it here for i/o efficiency (page/sector boundaries and all that).
Note: the efficiency gain has not been verified. */
- saved_record_size = file_pos % read_size;
- if (saved_record_size == 0)
- saved_record_size = read_size;
- file_pos -= saved_record_size;
- /* 'file_pos' now points to the start of the last (probably partial) block
- in the input file. */
+ size_t remainder = file_pos % read_size;
+ if (remainder != 0)
+ {
+ file_pos -= remainder;
+ if (lseek (input_fd, file_pos, SEEK_SET) < 0)
+ error (0, errno, _("%s: seek failed"), quotearg_colon (file));
+ }
- if (lseek (input_fd, file_pos, SEEK_SET) < 0)
- error (0, errno, _("%s: seek failed"), quotearg_colon (file));
+ /* Scan backward, looking for end of file. This caters to proc-like
+ file systems where the file size is just an estimate. */
+ while ((saved_record_size = safe_read (input_fd, G_buffer, read_size)) == 0
+ && file_pos != 0)
+ {
+ off_t rsize = read_size;
+ if (lseek (input_fd, -rsize, SEEK_CUR) < 0)
+ error (0, errno, _("%s: seek failed"), quotearg_colon (file));
+ file_pos -= read_size;
+ }
- if (safe_read (input_fd, G_buffer, saved_record_size) != saved_record_size)
+ /* Now scan forward, looking for end of file. */
+ while (saved_record_size == read_size)
+ {
+ size_t nread = safe_read (input_fd, G_buffer, read_size);
+ if (nread == 0)
+ break;
+ saved_record_size = nread;
+ if (saved_record_size == SAFE_READ_ERROR)
+ break;
+ file_pos += nread;
+ }
+
+ if (saved_record_size == SAFE_READ_ERROR)
{
error (0, errno, _("%s: read error"), quotearg_colon (file));
return false;
@@ -282,8 +296,8 @@ tac_seekable (int input_fd, const char *file)
{
/* 'match_length' is constant for non-regexp boundaries. */
while (*--match_start != first_char
- || (match_length1 && strncmp (match_start + 1, separator1,
- match_length1)))
+ || (match_length1 && !STREQ_LEN (match_start + 1, separator1,
+ match_length1)))
/* Do nothing. */ ;
}
@@ -307,8 +321,6 @@ tac_seekable (int input_fd, const char *file)
'G_buffer_size'. */
char *newbuffer;
size_t offset = sentinel_length ? sentinel_length : 1;
- ptrdiff_t match_start_offset = match_start - G_buffer;
- ptrdiff_t past_end_offset = past_end - G_buffer;
size_t old_G_buffer_size = G_buffer_size;
read_size *= 2;
@@ -317,9 +329,6 @@ tac_seekable (int input_fd, const char *file)
xalloc_die ();
newbuffer = xrealloc (G_buffer - offset, G_buffer_size);
newbuffer += offset;
- /* Adjust the pointers for the new buffer location. */
- match_start = newbuffer + match_start_offset;
- past_end = newbuffer + past_end_offset;
G_buffer = newbuffer;
}
@@ -485,15 +494,16 @@ temp_stream (FILE **fp, char **file_name)
/* Copy from file descriptor INPUT_FD (corresponding to the named FILE) to
a temporary file, and set *G_TMP and *G_TEMPFILE to the resulting stream
- and file name. Return true if successful. */
+ and file name. Return the number of bytes copied, or -1 on error. */
-static bool
+static off_t
copy_to_temp (FILE **g_tmp, char **g_tempfile, int input_fd, char const *file)
{
FILE *fp;
char *file_name;
+ uintmax_t bytes_copied = 0;
if (!temp_stream (&fp, &file_name))
- return false;
+ return -1;
while (1)
{
@@ -511,6 +521,11 @@ copy_to_temp (FILE **g_tmp, char **g_tempfile, int input_fd, char const *file)
error (0, errno, _("%s: write error"), quotearg_colon (file_name));
goto Fail;
}
+
+ /* Implicitly <= OFF_T_MAX due to preceding fwrite(),
+ but unsigned type used to avoid compiler warnings
+ not aware of this fact. */
+ bytes_copied += bytes_read;
}
if (fflush (fp) != 0)
@@ -521,11 +536,11 @@ copy_to_temp (FILE **g_tmp, char **g_tempfile, int input_fd, char const *file)
*g_tmp = fp;
*g_tempfile = file_name;
- return true;
+ return bytes_copied;
Fail:
fclose (fp);
- return false;
+ return -1;
}
/* Copy INPUT_FD to a temporary, then tac that file.
@@ -536,10 +551,11 @@ tac_nonseekable (int input_fd, const char *file)
{
FILE *tmp_stream;
char *tmp_file;
- if (!copy_to_temp (&tmp_stream, &tmp_file, input_fd, file))
+ off_t bytes_copied = copy_to_temp (&tmp_stream, &tmp_file, input_fd, file);
+ if (bytes_copied < 0)
return false;
- bool ok = tac_seekable (fileno (tmp_stream), tmp_file);
+ bool ok = tac_seekable (fileno (tmp_stream), tmp_file, bytes_copied);
return ok;
}
@@ -578,7 +594,7 @@ tac_file (const char *filename)
ok = (file_size < 0 || isatty (fd)
? tac_nonseekable (fd, filename)
- : tac_seekable (fd, filename));
+ : tac_seekable (fd, filename, file_size));
if (!is_stdin && close (fd) != 0)
{
@@ -699,5 +715,5 @@ main (int argc, char **argv)
free (G_buffer - offset);
#endif
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/tail.c b/src/tail.c
index 5ff738df..c062d403 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -1,5 +1,5 @@
/* tail -- output the last part of file(s)
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -40,9 +40,11 @@
#include "posixver.h"
#include "quote.h"
#include "safe-read.h"
+#include "stat-size.h"
#include "stat-time.h"
#include "xfreopen.h"
#include "xnanosleep.h"
+#include "xdectoint.h"
#include "xstrtol.h"
#include "xstrtod.h"
@@ -157,13 +159,6 @@ struct File_spec
uintmax_t n_unchanged_stats;
};
-#if HAVE_INOTIFY
-/* The events mask used with inotify on files. This mask is not used on
- directories. */
-static const uint32_t inotify_wd_mask = (IN_MODIFY | IN_ATTRIB
- | IN_DELETE_SELF | IN_MOVE_SELF);
-#endif
-
/* Keep trying to open a file even if it is inaccessible when tail starts
or if it becomes inaccessible later -- useful only with -f. */
static bool reopen_inaccessible_files;
@@ -262,9 +257,9 @@ Usage: %s [OPTION]... [FILE]...\n\
printf (_("\
Print the last %d lines of each FILE to standard output.\n\
With more than one FILE, precede each with a header giving the file name.\n\
-With no FILE, or when FILE is -, read standard input.\n\
"), DEFAULT_N_LINES);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -321,7 +316,7 @@ track the actual name of the file, not the file descriptor (e.g., log\n\
rotation). Use --follow=name in that case. That causes tail to track the\n\
named file in a way that accommodates renaming, removal and creation.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -930,12 +925,10 @@ fremote (int fd, const char *name)
# define fremote(fd, name) false
#endif
-/* FIXME: describe */
-
+/* open/fstat F->name and handle changes. */
static void
recheck (struct File_spec *f, bool blocking)
{
- /* open/fstat the file and announce if dev/ino have changed */
struct stat new_stats;
bool ok = true;
bool is_stdin = (STREQ (f->name, "-"));
@@ -1026,42 +1019,45 @@ recheck (struct File_spec *f, bool blocking)
assert (f->fd == -1);
error (0, 0, _("%s has become accessible"), quote (pretty_name (f)));
}
+ else if (f->fd == -1)
+ {
+ /* A new file even when inodes haven't changed as <dev,inode>
+ pairs can be reused, and we know the file was missing
+ on the previous iteration. Note this also means the file
+ is redisplayed in --follow=name mode if renamed away from
+ and back to a monitored name. */
+ new_file = true;
+
+ error (0, 0,
+ _("%s has appeared; following new file"),
+ quote (pretty_name (f)));
+ }
else if (f->ino != new_stats.st_ino || f->dev != new_stats.st_dev)
{
+ /* File has been replaced (e.g., via log rotation) --
+ tail the new one. */
new_file = true;
- if (f->fd == -1)
- {
- error (0, 0,
- _("%s has appeared; following end of new file"),
- quote (pretty_name (f)));
- }
- else
- {
- /* Close the old one. */
- close_fd (f->fd, pretty_name (f));
-
- /* File has been replaced (e.g., via log rotation) --
- tail the new one. */
- error (0, 0,
- _("%s has been replaced; following end of new file"),
- quote (pretty_name (f)));
- }
+
+ error (0, 0,
+ _("%s has been replaced; following new file"),
+ quote (pretty_name (f)));
+
+ /* Close the old one. */
+ close_fd (f->fd, pretty_name (f));
+
}
else
{
- if (f->fd == -1)
- {
- /* This happens when one iteration finds the file missing,
- then the preceding <dev,inode> pair is reused as the
- file is recreated. */
- new_file = true;
- }
- else
- {
- close_fd (fd, pretty_name (f));
- }
+ /* No changes detected, so close new fd. */
+ close_fd (fd, pretty_name (f));
}
+ /* FIXME: When a log is rotated, daemons tend to log to the
+ old file descriptor until the new file is present and
+ the daemon is sent a signal. Therefore tail may miss entries
+ being written to the old file. Perhaps we should keep
+ the older file open and continue to monitor it until
+ data is written to a new file. */
if (new_file)
{
/* Start at the beginning of the file. */
@@ -1200,13 +1196,16 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
/* reset counter */
f[i].n_unchanged_stats = 0;
+ /* XXX: This is only a heuristic, as the file may have also
+ been truncated and written to if st_size >= size
+ (in which case we ignore new data <= size). */
if (S_ISREG (mode) && stats.st_size < f[i].size)
{
error (0, 0, _("%s: file truncated"), name);
- last = i;
- xlseek (fd, stats.st_size, SEEK_SET, name);
- f[i].size = stats.st_size;
- continue;
+ /* Assume the file was truncated to 0,
+ and therefore output all "new" data. */
+ xlseek (fd, 0, SEEK_SET, name);
+ f[i].size = 0;
}
if (i != last)
@@ -1317,9 +1316,9 @@ wd_comparator (const void *e1, const void *e2)
return spec1->wd == spec2->wd;
}
-/* Helper function used by 'tail_forever_inotify'. */
+/* Output (new) data for FSPEC->fd. */
static void
-check_fspec (struct File_spec *fspec, int wd, int *prev_wd)
+check_fspec (struct File_spec *fspec, struct File_spec **prev_fspec)
{
struct stat stats;
char const *name;
@@ -1337,22 +1336,26 @@ check_fspec (struct File_spec *fspec, int wd, int *prev_wd)
return;
}
+ /* XXX: This is only a heuristic, as the file may have also
+ been truncated and written to if st_size >= size
+ (in which case we ignore new data <= size).
+ Though in the inotify case it's more likely we'll get
+ separate events for truncate() and write(). */
if (S_ISREG (fspec->mode) && stats.st_size < fspec->size)
{
error (0, 0, _("%s: file truncated"), name);
- *prev_wd = wd;
- xlseek (fspec->fd, stats.st_size, SEEK_SET, name);
- fspec->size = stats.st_size;
+ xlseek (fspec->fd, 0, SEEK_SET, name);
+ fspec->size = 0;
}
else if (S_ISREG (fspec->mode) && stats.st_size == fspec->size
&& timespec_cmp (fspec->mtime, get_stat_mtime (&stats)) == 0)
return;
- if (wd != *prev_wd)
+ if (fspec != *prev_fspec)
{
if (print_headers)
write_header (name);
- *prev_wd = wd;
+ *prev_fspec = fspec;
}
uintmax_t bytes_read = dump_remainder (name, fspec->fd, COPY_TO_EOF);
@@ -1369,16 +1372,22 @@ static bool
tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
double sleep_interval)
{
+# if TAIL_TEST_SLEEP
+ /* Delay between open() and inotify_add_watch()
+ to help trigger different cases. */
+ xnanosleep (1000000);
+# endif
unsigned int max_realloc = 3;
/* Map an inotify watch descriptor to the name of the file it's watching. */
Hash_table *wd_to_name;
bool found_watchable_file = false;
+ bool tailed_but_unwatchable = false;
bool found_unwatchable_dir = false;
bool no_inotify_resources = false;
bool writer_is_dead = false;
- int prev_wd;
+ struct File_spec *prev_fspec;
size_t evlen = 0;
char *evbuf;
size_t evbuf_off = 0;
@@ -1388,6 +1397,13 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
if (! wd_to_name)
xalloc_die ();
+ /* The events mask used with inotify on files (not directories). */
+ uint32_t inotify_wd_mask = IN_MODIFY;
+ /* TODO: Perhaps monitor these events in Follow_descriptor mode also,
+ to tag reported file names with "deleted", "moved" etc. */
+ if (follow_mode == Follow_name)
+ inotify_wd_mask |= (IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF);
+
/* Add an inotify watch for each watched file. If -F is specified then watch
its parent directory too, in this way when they re-appear we can add them
again to the watch list. */
@@ -1436,10 +1452,13 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
if (f[i].wd < 0)
{
- if (errno == ENOSPC)
+ if (f[i].fd != -1) /* already tailed. */
+ tailed_but_unwatchable = true;
+ if (errno == ENOSPC || errno == ENOMEM)
{
no_inotify_resources = true;
error (0, 0, _("inotify resources exhausted"));
+ break;
}
else if (errno != f[i].errnum)
error (0, errno, _("cannot watch %s"), quote (f[i].name));
@@ -1456,24 +1475,53 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
/* Linux kernel 2.6.24 at least has a bug where eventually, ENOSPC is always
returned by inotify_add_watch. In any case we should revert to polling
when there are no inotify resources. Also a specified directory may not
- be currently present or accessible, so revert to polling. */
- if (no_inotify_resources || found_unwatchable_dir)
+ be currently present or accessible, so revert to polling. Also an already
+ tailed but unwatchable due rename/unlink race, should also revert. */
+ if (no_inotify_resources || found_unwatchable_dir
+ || (follow_mode == Follow_descriptor && tailed_but_unwatchable))
{
- /* FIXME: release hash and inotify resources allocated above. */
+ hash_free (wd_to_name);
+
errno = 0;
return true;
}
if (follow_mode == Follow_descriptor && !found_watchable_file)
return false;
- prev_wd = f[n_files - 1].wd;
+ prev_fspec = &(f[n_files - 1]);
- /* Check files again. New data can be available since last time we checked
- and before they are watched by inotify. */
+ /* Check files again. New files or data can be available since last time we
+ checked and before they are watched by inotify. */
for (i = 0; i < n_files; i++)
{
- if (!f[i].ignore)
- check_fspec (&f[i], f[i].wd, &prev_wd);
+ if (! f[i].ignore)
+ {
+ /* check for new files. */
+ if (follow_mode == Follow_name)
+ recheck (&(f[i]), false);
+ else if (f[i].fd != -1)
+ {
+ /* If the file was replaced in the small window since we tailed,
+ then assume the watch is on the wrong item (different to
+ that we've already produced output for), and so revert to
+ polling the original descriptor. */
+ struct stat stats;
+
+ if (stat (f[i].name, &stats) == 0
+ && (f[i].dev != stats.st_dev || f[i].ino != stats.st_ino))
+ {
+ error (0, errno, _("%s was replaced"),
+ quote (pretty_name (&(f[i]))));
+ hash_free (wd_to_name);
+
+ errno = 0;
+ return true;
+ }
+ }
+
+ /* check for new data. */
+ check_fspec (&f[i], &prev_fspec);
+ }
}
evlen += sizeof (struct inotify_event) + 1;
@@ -1553,7 +1601,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
ev = void_ev;
evbuf_off += sizeof (*ev) + ev->len;
- if (ev->len) /* event on ev->name in watched directory */
+ if (ev->len) /* event on ev->name in watched directory. */
{
size_t j;
for (j = 0; j < n_files; j++)
@@ -1569,35 +1617,58 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
if (j == n_files)
continue;
- /* It's fine to add the same file more than once. */
+ fspec = &(f[j]);
+
+ /* Adding the same inode again will look up any existing wd. */
int new_wd = inotify_add_watch (wd, f[j].name, inotify_wd_mask);
if (new_wd < 0)
{
- /* Can get ENOENT for a dangling symlink for example. */
- error (0, errno, _("cannot watch %s"), quote (f[j].name));
- continue;
+ if (errno == ENOSPC || errno == ENOMEM)
+ {
+ error (0, 0, _("inotify resources exhausted"));
+ hash_free (wd_to_name);
+ errno = 0;
+ return true; /* revert to polling. */
+ }
+ else
+ {
+ /* Can get ENOENT for a dangling symlink for example. */
+ error (0, errno, _("cannot watch %s"), quote (f[j].name));
+ }
+ /* We'll continue below after removing the existing watch. */
}
- fspec = &(f[j]);
-
- /* Remove 'fspec' and re-add it using 'new_fd' as its key. */
- hash_delete (wd_to_name, fspec);
- fspec->wd = new_wd;
+ /* This will be false if only attributes of file change. */
+ bool new_watch = fspec->wd < 0 || new_wd != fspec->wd;
- /* If the file was moved then inotify will use the source file wd for
- the destination file. Make sure the key is not present in the
- table. */
- struct File_spec *prev = hash_delete (wd_to_name, fspec);
- if (prev && prev != fspec)
+ if (new_watch)
{
- if (follow_mode == Follow_name)
- recheck (prev, false);
- prev->wd = -1;
- close_fd (prev->fd, pretty_name (prev));
- }
+ if (0 <= fspec->wd)
+ {
+ inotify_rm_watch (wd, fspec->wd);
+ hash_delete (wd_to_name, fspec);
+ }
- if (hash_insert (wd_to_name, fspec) == NULL)
- xalloc_die ();
+ fspec->wd = new_wd;
+
+ if (new_wd == -1)
+ continue;
+
+ /* If the file was moved then inotify will use the source file wd
+ for the destination file. Make sure the key is not present in
+ the table. */
+ struct File_spec *prev = hash_delete (wd_to_name, fspec);
+ if (prev && prev != fspec)
+ {
+ if (follow_mode == Follow_name)
+ recheck (prev, false);
+ prev->wd = -1;
+ close_fd (prev->fd, pretty_name (prev));
+ }
+
+ if (hash_insert (wd_to_name, fspec) == NULL)
+ xalloc_die ();
+ }
if (follow_mode == Follow_name)
recheck (fspec, false);
@@ -1614,24 +1685,21 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
if (ev->mask & (IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF))
{
- /* For IN_DELETE_SELF, we always want to remove the watch.
- However, for IN_MOVE_SELF (the file we're watching has
- been clobbered via a rename), when tailing by NAME, we
- must continue to watch the file. It's only when following
- by file descriptor that we must remove the watch. */
- if ((ev->mask & IN_DELETE_SELF)
- || ((ev->mask & IN_MOVE_SELF)
- && follow_mode == Follow_descriptor))
+ /* Note for IN_MOVE_SELF (the file we're watching has
+ been clobbered via a rename) we leave the watch
+ in place since it may still be part of the set
+ of watched names. */
+ if (ev->mask & IN_DELETE_SELF)
{
inotify_rm_watch (wd, fspec->wd);
hash_delete (wd_to_name, fspec);
}
- if (follow_mode == Follow_name)
- recheck (fspec, false);
+
+ recheck (fspec, false);
continue;
}
- check_fspec (fspec, ev->wd, &prev_wd);
+ check_fspec (fspec, &prev_fspec);
}
}
#endif
@@ -1665,40 +1733,30 @@ tail_bytes (const char *pretty_filename, int fd, uintmax_t n_bytes,
if (t)
return t < 0;
}
- *read_pos += dump_remainder (pretty_filename, fd, COPY_TO_EOF);
+ n_bytes = COPY_TO_EOF;
}
else
{
- if ( ! presume_input_pipe
- && S_ISREG (stats.st_mode) && n_bytes <= OFF_T_MAX)
+ off_t end_pos = ((! presume_input_pipe && usable_st_size (&stats)
+ && n_bytes <= OFF_T_MAX)
+ ? stats.st_size : -1);
+ if (end_pos <= ST_BLKSIZE (stats))
+ return pipe_bytes (pretty_filename, fd, n_bytes, read_pos);
+ off_t current_pos = xlseek (fd, 0, SEEK_CUR, pretty_filename);
+ if (current_pos < end_pos)
{
- off_t current_pos = xlseek (fd, 0, SEEK_CUR, pretty_filename);
- off_t end_pos = xlseek (fd, 0, SEEK_END, pretty_filename);
- off_t diff = end_pos - current_pos;
- /* Be careful here. The current position may actually be
- beyond the end of the file. */
- off_t bytes_remaining = diff < 0 ? 0 : diff;
- off_t nb = n_bytes;
-
- if (bytes_remaining <= nb)
- {
- /* From the current position to end of file, there are no
- more bytes than have been requested. So reposition the
- file pointer to the incoming current position and print
- everything after that. */
- *read_pos = xlseek (fd, current_pos, SEEK_SET, pretty_filename);
- }
- else
+ off_t bytes_remaining = end_pos - current_pos;
+
+ if (n_bytes < bytes_remaining)
{
- /* There are more bytes remaining than were requested.
- Back up. */
- *read_pos = xlseek (fd, -nb, SEEK_END, pretty_filename);
+ current_pos = end_pos - n_bytes;
+ xlseek (fd, current_pos, SEEK_SET, pretty_filename);
}
- *read_pos += dump_remainder (pretty_filename, fd, n_bytes);
}
- else
- return pipe_bytes (pretty_filename, fd, n_bytes, read_pos);
+ *read_pos = current_pos;
}
+
+ *read_pos += dump_remainder (pretty_filename, fd, n_bytes);
return true;
}
@@ -1826,7 +1884,7 @@ tail_file (struct File_spec *f, uintmax_t n_units)
{
struct stat stats;
-#if TEST_RACE_BETWEEN_FINAL_READ_AND_INITIAL_FSTAT
+#if TAIL_TEST_SLEEP
/* Before the tail function provided 'read_pos', there was
a race condition described in the URL below. This sleep
call made the window big enough to exercise the problem. */
@@ -1958,7 +2016,10 @@ parse_obsolete_option (int argc, char * const *argv, uintmax_t *n_units)
else if ((xstrtoumax (n_string, NULL, 10, n_units, "b")
& ~LONGINT_INVALID_SUFFIX_CHAR)
!= LONGINT_OK)
- error (EXIT_FAILURE, 0, _("number in %s is too large"), quote (argv[1]));
+ {
+ error (EXIT_FAILURE, errno, "%s: %s", _("invalid number"),
+ quote (argv[1]));
+ }
/* Set globals. */
from_start = t_from_start;
@@ -1995,17 +2056,10 @@ parse_options (int argc, char **argv,
else if (*optarg == '-')
++optarg;
- {
- strtol_error s_err;
- s_err = xstrtoumax (optarg, NULL, 10, n_units, "bkKmMGTPEZY0");
- if (s_err != LONGINT_OK)
- {
- error (EXIT_FAILURE, 0, "%s: %s", optarg,
- (c == 'n'
- ? _("invalid number of lines")
- : _("invalid number of bytes")));
- }
- }
+ *n_units = xdectoumax (optarg, 0, UINTMAX_MAX, "bkKmMGTPEZY0",
+ count_lines
+ ? _("invalid number of lines")
+ : _("invalid number of bytes"), 0);
break;
case 'f':
@@ -2024,15 +2078,9 @@ parse_options (int argc, char **argv,
case MAX_UNCHANGED_STATS_OPTION:
/* --max-unchanged-stats=N */
- if (xstrtoumax (optarg, NULL, 10,
- &max_n_unchanged_stats_between_opens,
- "")
- != LONGINT_OK)
- {
- error (EXIT_FAILURE, 0,
- _("%s: invalid maximum number of unchanged stats between opens"),
- optarg);
- }
+ max_n_unchanged_stats_between_opens =
+ xdectoumax (optarg, 0, UINTMAX_MAX, "",
+ _("invalid maximum number of unchanged stats between opens"), 0);
break;
case DISABLE_INOTIFY_OPTION:
@@ -2040,16 +2088,7 @@ parse_options (int argc, char **argv,
break;
case PID_OPTION:
- {
- strtol_error s_err;
- unsigned long int tmp_ulong;
- s_err = xstrtoul (optarg, NULL, 10, &tmp_ulong, "");
- if (s_err != LONGINT_OK || tmp_ulong > PID_T_MAX)
- {
- error (EXIT_FAILURE, 0, _("%s: invalid PID"), optarg);
- }
- pid = tmp_ulong;
- }
+ pid = xdectoumax (optarg, 0, PID_T_MAX, "", _("invalid PID"), 0);
break;
case PRESUME_INPUT_PIPE_OPTION:
@@ -2065,7 +2104,7 @@ parse_options (int argc, char **argv,
double s;
if (! (xstrtod (optarg, NULL, &s, c_strtod) && 0 <= s))
error (EXIT_FAILURE, 0,
- _("%s: invalid number of seconds"), optarg);
+ _("invalid number of seconds: %s"), quote (optarg));
*sleep_interval = s;
}
break;
@@ -2185,6 +2224,8 @@ main (int argc, char **argv)
--n_units;
}
+ IF_LINT (assert (0 <= argc));
+
if (optind < argc)
{
n_files = argc - optind;
@@ -2218,7 +2259,7 @@ main (int argc, char **argv)
/* Don't read anything if we'll never output anything. */
if (! n_units && ! forever && ! from_start)
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
F = xnmalloc (n_files, sizeof *F);
for (i = 0; i < n_files; i++)
@@ -2267,7 +2308,12 @@ main (int argc, char **argv)
FIXME: when using inotify, and a directory for a watched file
is recreated, then we don't recheck any new file when
- follow_mode == Follow_name */
+ follow_mode == Follow_name.
+
+ FIXME-maybe: inotify has a watch descriptor per inode, and hence with
+ our current hash implementation will only --follow data for one
+ of the names when multiple hardlinked files are specified, or
+ for one name when a name is specified multiple times. */
if (!disable_inotify && (tailable_stdin (F, n_files)
|| any_remote_file (F, n_files)
|| any_symlinks (F, n_files)
@@ -2285,10 +2331,23 @@ main (int argc, char **argv)
if (fflush (stdout) != 0)
error (EXIT_FAILURE, errno, _("write error"));
- if (!tail_forever_inotify (wd, F, n_files, sleep_interval))
- exit (EXIT_FAILURE);
+ if (! tail_forever_inotify (wd, F, n_files, sleep_interval))
+ return EXIT_FAILURE;
}
error (0, errno, _("inotify cannot be used, reverting to polling"));
+
+ /* Free resources as this process can be long lived,
+ and we may have exhausted system resources above. */
+
+ for (i = 0; i < n_files; i++)
+ {
+ /* It's OK to remove the same watch multiple times,
+ ignoring the EINVAL from redundant calls. */
+ if (F[i].wd != -1)
+ inotify_rm_watch (wd, F[i].wd);
+ if (F[i].parent_wd != -1)
+ inotify_rm_watch (wd, F[i].parent_wd);
+ }
}
#endif
disable_inotify = true;
@@ -2297,5 +2356,5 @@ main (int argc, char **argv)
if (have_read_stdin && close (STDIN_FILENO) < 0)
error (EXIT_FAILURE, errno, "-");
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/tee.c b/src/tee.c
index be365604..3c39a4ab 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -1,5 +1,5 @@
/* tee - read from standard input and write to standard output and files.
- Copyright (C) 1985-2014 Free Software Foundation, Inc.
+ Copyright (C) 1985-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
#include <getopt.h>
#include "system.h"
+#include "argmatch.h"
#include "error.h"
#include "fadvise.h"
#include "stdio--.h"
@@ -43,15 +44,38 @@ static bool append;
/* If true, ignore interrupts. */
static bool ignore_interrupts;
+enum output_error
+ {
+ output_error_sigpipe, /* traditional behavior, sigpipe enabled. */
+ output_error_warn, /* warn on EPIPE, but continue. */
+ output_error_warn_nopipe, /* ignore EPIPE, continue. */
+ output_error_exit, /* exit on any output error. */
+ output_error_exit_nopipe /* exit on any output error except EPIPE. */
+ };
+
+static enum output_error output_error;
+
static struct option const long_options[] =
{
{"append", no_argument, NULL, 'a'},
{"ignore-interrupts", no_argument, NULL, 'i'},
+ {"output-error", optional_argument, NULL, 'p'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
};
+static char const *const output_error_args[] =
+{
+ "warn", "warn-nopipe", "exit", "exit-nopipe", NULL
+};
+static enum output_error const output_error_types[] =
+{
+ output_error_warn, output_error_warn_nopipe,
+ output_error_exit, output_error_exit_nopipe
+};
+ARGMATCH_VERIFY (output_error_args, output_error_types);
+
void
usage (int status)
{
@@ -66,13 +90,24 @@ Copy standard input to each FILE, and also to standard output.\n\
-a, --append append to the given FILEs, do not overwrite\n\
-i, --ignore-interrupts ignore interrupt signals\n\
"), stdout);
+ fputs (_("\
+ -p, --output-error[=MODE] behavior on write error. See MODE details below\n\
+"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
\n\
-If a FILE is -, copy again to standard output.\n\
+MODE determines behavior with write errors on the outputs:\n\
+ 'warn' diagnose errors writing to any output\n\
+ 'warn-nopipe' diagnose errors writing to any output not a pipe\n\
+ 'exit' exit on error writing to any output\n\
+ 'exit-nopipe' exit on error writing to any output not a pipe\n\
+The default MODE for the -p option is 'warn-nopipe'.\n\
+The default operation when --output-error is not specified, is to\n\
+exit immediately on error writing to a pipe, and diagnose errors\n\
+writing to non pipe outputs.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -94,7 +129,7 @@ main (int argc, char **argv)
append = false;
ignore_interrupts = false;
- while ((optc = getopt_long (argc, argv, "ai", long_options, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "aip", long_options, NULL)) != -1)
{
switch (optc)
{
@@ -106,6 +141,14 @@ main (int argc, char **argv)
ignore_interrupts = true;
break;
+ case 'p':
+ if (optarg)
+ output_error = XARGMATCH ("--output-error", optarg,
+ output_error_args, output_error_types);
+ else
+ output_error = output_error_warn_nopipe;
+ break;
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -118,6 +161,9 @@ main (int argc, char **argv)
if (ignore_interrupts)
signal (SIGINT, SIG_IGN);
+ if (output_error != output_error_sigpipe)
+ signal (SIGPIPE, SIG_IGN);
+
/* Do *not* warn if tee is given no file arguments.
POSIX requires that it work when given no arguments. */
@@ -125,7 +171,7 @@ main (int argc, char **argv)
if (close (STDIN_FILENO) != 0)
error (EXIT_FAILURE, errno, _("standard input"));
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
/* Copy the standard input into each of the NFILES files in FILES
@@ -135,9 +181,10 @@ main (int argc, char **argv)
static bool
tee_files (int nfiles, const char **files)
{
+ size_t n_outputs = 0;
FILE **descriptors;
char buffer[BUFSIZ];
- ssize_t bytes_read;
+ ssize_t bytes_read = 0;
int i;
bool ok = true;
char const *mode_string =
@@ -164,22 +211,27 @@ tee_files (int nfiles, const char **files)
descriptors[0] = stdout;
files[0] = _("standard output");
setvbuf (stdout, NULL, _IONBF, 0);
+ n_outputs++;
for (i = 1; i <= nfiles; i++)
{
- descriptors[i] = (STREQ (files[i], "-")
- ? stdout
- : fopen (files[i], mode_string));
+ /* Do not treat "-" specially - as mandated by POSIX. */
+ descriptors[i] = fopen (files[i], mode_string);
if (descriptors[i] == NULL)
{
- error (0, errno, "%s", files[i]);
+ error (output_error == output_error_exit
+ || output_error == output_error_exit_nopipe,
+ errno, "%s", files[i]);
ok = false;
}
else
- setvbuf (descriptors[i], NULL, _IONBF, 0);
+ {
+ setvbuf (descriptors[i], NULL, _IONBF, 0);
+ n_outputs++;
+ }
}
- while (1)
+ while (n_outputs)
{
bytes_read = read (0, buffer, sizeof buffer);
if (bytes_read < 0 && errno == EINTR)
@@ -193,9 +245,21 @@ tee_files (int nfiles, const char **files)
if (descriptors[i]
&& fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
{
- error (0, errno, "%s", files[i]);
+ int w_errno = errno;
+ bool fail = errno != EPIPE || (output_error == output_error_exit
+ || output_error == output_error_warn);
+ if (descriptors[i] == stdout)
+ clearerr (stdout); /* Avoid redundant close_stdout diagnostic. */
+ if (fail)
+ {
+ error (output_error == output_error_exit
+ || output_error == output_error_exit_nopipe,
+ w_errno, "%s", files[i]);
+ }
descriptors[i] = NULL;
- ok = false;
+ if (fail)
+ ok = false;
+ n_outputs--;
}
}
@@ -207,8 +271,7 @@ tee_files (int nfiles, const char **files)
/* Close the files, but not standard output. */
for (i = 1; i <= nfiles; i++)
- if (!STREQ (files[i], "-")
- && descriptors[i] && fclose (descriptors[i]) != 0)
+ if (descriptors[i] && fclose (descriptors[i]) != 0)
{
error (0, errno, "%s", files[i]);
ok = false;
diff --git a/src/test.c b/src/test.c
index 75968798..80cc679c 100644
--- a/src/test.c
+++ b/src/test.c
@@ -2,7 +2,7 @@
/* Modified to run with the GNU shell by bfox. */
-/* Copyright (C) 1987-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -57,10 +57,12 @@ enum { TEST_TRUE, TEST_FALSE, TEST_FAILURE };
#if defined TEST_STANDALONE
# define test_exit(val) exit (val)
+# define test_main_return(val) return val
#else
static jmp_buf test_exit_buf;
static int test_error_return = 0;
# define test_exit(val) test_error_return = val, longjmp (test_exit_buf, 1)
+# define test_main_return(val) test_exit (val)
#endif /* !TEST_STANDALONE */
static int pos; /* The offset of the current argument in ARGV. */
@@ -789,7 +791,7 @@ NOTE: [ honors the --help and --version options, but test does not.\n\
test treats each of those as it treats any other nonempty STRING.\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, _("test and/or ["));
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -851,7 +853,7 @@ main (int margc, char **margv)
{
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
(char *) NULL);
- test_exit (EXIT_SUCCESS);
+ test_main_return (EXIT_SUCCESS);
}
}
if (margc < 2 || !STREQ (margv[margc - 1], "]"))
@@ -864,12 +866,12 @@ main (int margc, char **margv)
pos = 1;
if (pos >= argc)
- test_exit (TEST_FALSE);
+ test_main_return (TEST_FALSE);
value = posixtest (argc - 1);
if (pos != argc)
test_syntax_error (_("extra argument %s"), quote (argv[pos]));
- test_exit (value ? TEST_TRUE : TEST_FALSE);
+ test_main_return (value ? TEST_TRUE : TEST_FALSE);
}
diff --git a/src/timeout.c b/src/timeout.c
index 68baa23c..98378f6f 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -1,5 +1,5 @@
/* timeout -- run a command with bounded time
- Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -203,15 +203,17 @@ cleanup (int sig)
in case it has itself become group leader,
or is not running in a separate group. */
send_sig (monitored_pid, sig);
+
/* The normal case is the job has remained in our
newly created process group, so send to all processes in that. */
if (!foreground)
- send_sig (0, sig);
- if (sig != SIGKILL && sig != SIGCONT)
{
- send_sig (monitored_pid, SIGCONT);
- if (!foreground)
- send_sig (0, SIGCONT);
+ send_sig (0, sig);
+ if (sig != SIGKILL && sig != SIGCONT)
+ {
+ send_sig (monitored_pid, SIGCONT);
+ send_sig (0, SIGCONT);
+ }
}
}
else /* we're the child or the child is not exec'd yet. */
@@ -266,7 +268,7 @@ is specified, send the TERM signal upon timeout. The TERM signal kills\n\
any process that does not block or catch that signal. It may be necessary\n\
to use the KILL (9) signal, since this signal cannot be caught, in which\n\
case the exit status is 128+9 rather than 124.\n"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -440,12 +442,10 @@ main (int argc, char **argv)
if (monitored_pid == -1)
{
error (0, errno, _("fork system call failed"));
- exit (EXIT_CANCELED);
+ return EXIT_CANCELED;
}
else if (monitored_pid == 0)
{ /* child */
- int exit_status;
-
/* exec doesn't reset SIG_IGN -> SIG_DFL. */
signal (SIGTTIN, SIG_DFL);
signal (SIGTTOU, SIG_DFL);
@@ -453,9 +453,9 @@ main (int argc, char **argv)
execvp (argv[0], argv); /* FIXME: should we use "sh -c" ... here? */
/* exit like sh, env, nohup, ... */
- exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
+ int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
error (0, errno, _("failed to run command %s"), quote (argv[0]));
- exit (exit_status);
+ return exit_status;
}
else
{
@@ -494,14 +494,13 @@ main (int argc, char **argv)
else
{
/* shouldn't happen. */
- error (0, 0, _("unknown status from command (0x%X)"), status);
+ error (0, 0, _("unknown status from command (%d)"), status);
status = EXIT_FAILURE;
}
}
if (timed_out && !preserve_status)
- exit (EXIT_TIMEDOUT);
- else
- exit (status);
+ status = EXIT_TIMEDOUT;
+ return status;
}
}
diff --git a/src/touch.c b/src/touch.c
index 1ba24269..628610a8 100644
--- a/src/touch.c
+++ b/src/touch.c
@@ -1,5 +1,5 @@
/* touch -- change modification and access times of files
- Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -247,7 +247,7 @@ change the times of the file associated with standard output.\n\
\n\
Note that the -d and -t options accept different time-date formats.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -433,5 +433,5 @@ main (int argc, char **argv)
for (; optind < argc; ++optind)
ok &= touch (argv[optind]);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/tr.c b/src/tr.c
index 06858f91..fe6f466b 100644
--- a/src/tr.c
+++ b/src/tr.c
@@ -1,5 +1,5 @@
/* tr -- a filter to translate characters
- Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ Copyright (C) 1991-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -346,7 +346,7 @@ only be used in pairs to specify case conversion. -s uses SET1 if not\n\
translating nor deleting; else squeezing uses SET2 and occurs after\n\
translation or deletion.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -1804,13 +1804,13 @@ main (int argc, char **argv)
spec_init (s1);
if (!parse_str (argv[optind], s1))
- exit (EXIT_FAILURE);
+ return EXIT_FAILURE;
if (non_option_args == 2)
{
spec_init (s2);
if (!parse_str (argv[optind + 1], s2))
- exit (EXIT_FAILURE);
+ return EXIT_FAILURE;
}
else
s2 = NULL;
@@ -1944,5 +1944,5 @@ main (int argc, char **argv)
if (close (STDIN_FILENO) != 0)
error (EXIT_FAILURE, errno, _("standard input"));
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/true.c b/src/true.c
index 8a1c4f92..22d141d0 100644
--- a/src/true.c
+++ b/src/true.c
@@ -1,5 +1,5 @@
/* Exit with a status code indicating success.
- Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Copyright (C) 1999-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,7 +47,7 @@ Usage: %s [ignored command line arguments]\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
exit (status);
}
@@ -76,5 +76,5 @@ main (int argc, char **argv)
(char *) NULL);
}
- exit (EXIT_STATUS);
+ return EXIT_STATUS;
}
diff --git a/src/truncate.c b/src/truncate.c
index f3125092..c40cd611 100644
--- a/src/truncate.c
+++ b/src/truncate.c
@@ -1,5 +1,5 @@
/* truncate -- truncate or extend the length of files.
- Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@
#include "error.h"
#include "quote.h"
#include "stat-size.h"
-#include "xstrtol.h"
+#include "xdectoint.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "truncate"
@@ -59,33 +59,6 @@ static struct option const longopts[] =
typedef enum
{ rm_abs = 0, rm_rel, rm_min, rm_max, rm_rdn, rm_rup } rel_mode_t;
-/* Set size to the value of STR, interpreted as a decimal integer,
- optionally multiplied by various values.
- Return -1 on error, 0 on success.
-
- This supports dd BLOCK size suffixes + lowercase g,t,m for bsd compat
- Note we don't support dd's b=512, c=1, w=2 or 21x512MiB formats. */
-static int
-parse_len (char const *str, off_t *size)
-{
- enum strtol_error e;
- intmax_t tmp_size;
- e = xstrtoimax (str, NULL, 10, &tmp_size, "EgGkKmMPtTYZ0");
- if (e == LONGINT_OK
- && !(OFF_T_MIN <= tmp_size && tmp_size <= OFF_T_MAX))
- e = LONGINT_OVERFLOW;
-
- if (e == LONGINT_OK)
- {
- errno = 0;
- *size = tmp_size;
- return 0;
- }
-
- errno = (e == LONGINT_OVERFLOW ? EOVERFLOW : 0);
- return -1;
-}
-
void
usage (int status)
{
@@ -122,7 +95,7 @@ reads as zero bytes.\n\
SIZE may also be prefixed by one of the following modifying characters:\n\
'+' extend by, '-' reduce by, '<' at most, '>' at least,\n\
'/' round down to multiple of, '%' round up to multiple of.\n"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -306,9 +279,10 @@ main (int argc, char **argv)
}
rel_mode = rm_rel;
}
- if (parse_len (optarg, &size) == -1)
- error (EXIT_FAILURE, errno, _("invalid number %s"),
- quote (optarg));
+ /* Support dd BLOCK size suffixes + lowercase g,t,m for bsd compat.
+ Note we don't support dd's b=512, c=1, w=2 or 21x512MiB formats. */
+ size = xdectoimax (optarg, OFF_T_MIN, OFF_T_MAX, "EgGkKmMPtTYZ0",
+ _("Invalid number"), 0);
/* Rounding to multiple of 0 is nonsensical */
if ((rel_mode == rm_rup || rel_mode == rm_rdn) && size == 0)
error (EXIT_FAILURE, 0, _("division by zero"));
@@ -420,5 +394,5 @@ main (int argc, char **argv)
}
}
- exit (errors ? EXIT_FAILURE : EXIT_SUCCESS);
+ return errors ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/tsort.c b/src/tsort.c
index 661c7173..d4be03d4 100644
--- a/src/tsort.c
+++ b/src/tsort.c
@@ -1,5 +1,5 @@
/* tsort - topological sort.
- Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ Copyright (C) 1998-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -82,12 +82,16 @@ usage (int status)
printf (_("\
Usage: %s [OPTION] [FILE]\n\
Write totally ordered list consistent with the partial ordering in FILE.\n\
-With no FILE, or when FILE is -, read standard input.\n\
-\n\
"), program_name);
+
+ emit_stdin_note ();
+
+ fputs (_("\
+\n\
+"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
@@ -557,5 +561,5 @@ main (int argc, char **argv)
ok = tsort (optind == argc ? "-" : argv[optind]);
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/tty.c b/src/tty.c
index 16301e12..eaa499e2 100644
--- a/src/tty.c
+++ b/src/tty.c
@@ -1,5 +1,5 @@
/* tty -- print the name of the terminal connected to standard input
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -69,7 +69,7 @@ Print the file name of the terminal connected to standard input.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -120,5 +120,5 @@ main (int argc, char **argv)
puts (_("not a tty"));
}
- exit (isatty (STDIN_FILENO) ? EXIT_SUCCESS : EXIT_FAILURE);
+ return isatty (STDIN_FILENO) ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/uname.c b/src/uname.c
index e3bed488..39bd28c7 100644
--- a/src/uname.c
+++ b/src/uname.c
@@ -1,6 +1,6 @@
/* uname -- print system information
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -148,7 +148,7 @@ Print machine architecture.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -371,5 +371,5 @@ main (int argc, char **argv)
putchar ('\n');
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/unexpand.c b/src/unexpand.c
index 505e223c..e0f7c22a 100644
--- a/src/unexpand.c
+++ b/src/unexpand.c
@@ -1,5 +1,5 @@
/* unexpand - convert blanks to tabs
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -116,9 +116,9 @@ Usage: %s [OPTION]... [FILE]...\n\
program_name);
fputs (_("\
Convert blanks in each FILE to tabs, writing to standard output.\n\
-With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
+ emit_stdin_note ();
emit_mandatory_arg_note ();
fputs (_("\
@@ -129,7 +129,7 @@ With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -528,5 +528,5 @@ main (int argc, char **argv)
if (have_read_stdin && fclose (stdin) != 0)
error (EXIT_FAILURE, errno, "-");
- exit (exit_status);
+ return exit_status;
}
diff --git a/src/uniq.c b/src/uniq.c
index 54200ff4..e0cfe4dd 100644
--- a/src/uniq.c
+++ b/src/uniq.c
@@ -1,5 +1,5 @@
/* uniq -- remove duplicate lines from a sorted file
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -185,15 +185,15 @@ With no options, matching lines are merged to the first occurrence.\n\
-d, --repeated only print duplicate lines, one for each group\n\
"), stdout);
fputs (_("\
- -D, --all-repeated[=METHOD] print all duplicate lines\n\
- groups can be delimited with an empty line\n\
+ -D, --all-repeated[=METHOD] print all duplicate lines;\n\
+ groups can be delimited with an empty line;\n\
METHOD={none(default),prepend,separate}\n\
"), stdout);
fputs (_("\
-f, --skip-fields=N avoid comparing the first N fields\n\
"), stdout);
fputs (_("\
- --group[=METHOD] show all items, separating groups with an empty line\n\
+ --group[=METHOD] show all items, separating groups with an empty line;\n\
METHOD={separate(default),prepend,append,both}\n\
"), stdout);
fputs (_("\
@@ -220,7 +220,7 @@ Note: 'uniq' does not detect repeated lines unless they are adjacent.\n\
You may want to sort the input first, or use 'sort -u' without 'uniq'.\n\
Also, comparisons honor the rules specified by 'LC_COLLATE'.\n\
"), stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -662,5 +662,5 @@ main (int argc, char **argv)
check_file (file[0], file[1], delimiter);
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/unlink.c b/src/unlink.c
index 260a5301..0b26fd4e 100644
--- a/src/unlink.c
+++ b/src/unlink.c
@@ -1,5 +1,5 @@
/* unlink utility for GNU.
- Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Copyright (C) 2001-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -49,7 +49,7 @@ Usage: %s FILE\n\
stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -85,5 +85,5 @@ main (int argc, char **argv)
if (unlink (argv[optind]) != 0)
error (EXIT_FAILURE, errno, _("cannot unlink %s"), quote (argv[optind]));
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/uptime.c b/src/uptime.c
index 4ab914f3..51233860 100644
--- a/src/uptime.c
+++ b/src/uptime.c
@@ -1,5 +1,5 @@
/* GNU's uptime.
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -217,7 +217,7 @@ If FILE is not specified, use %s. %s as FILE is common.\n\
UTMP_FILE, WTMP_FILE);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -253,5 +253,5 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/users.c b/src/users.c
index ee44c815..353753ca 100644
--- a/src/users.c
+++ b/src/users.c
@@ -1,5 +1,5 @@
/* GNU's users.
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -111,7 +111,7 @@ If FILE is not specified, use %s. %s as FILE is common.\n\
UTMP_FILE, WTMP_FILE);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -147,5 +147,5 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/wc.c b/src/wc.c
index 4909d9fe..9fbaee7b 100644
--- a/src/wc.c
+++ b/src/wc.c
@@ -1,5 +1,5 @@
/* wc - print the number of lines, words, and bytes in files
- Copyright (C) 1985-2014 Free Software Foundation, Inc.
+ Copyright (C) 1985-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,6 +36,7 @@
#include "quotearg.h"
#include "readtokens0.h"
#include "safe-read.h"
+#include "stat-size.h"
#include "xfreopen.h"
#if !defined iswspace && !HAVE_ISWSPACE
@@ -116,9 +117,14 @@ Usage: %s [OPTION]... [FILE]...\n\
program_name, program_name);
fputs (_("\
Print newline, word, and byte counts for each FILE, and a total line if\n\
-more than one FILE is specified. With no FILE, or when FILE is -,\n\
-read standard input. A word is a non-zero-length sequence of characters\n\
-delimited by white space.\n\
+more than one FILE is specified. A word is a non-zero-length sequence of\n\
+characters delimited by white space.\n\
+"), stdout);
+
+ emit_stdin_note ();
+
+ fputs (_("\
+\n\
The options below may be used to select which counts are printed, always in\n\
the following order: newline, word, character, byte, maximum line length.\n\
-c, --bytes print the byte counts\n\
@@ -129,12 +135,12 @@ the following order: newline, word, character, byte, maximum line length.\n\
--files0-from=F read input from the files specified by\n\
NUL-terminated names in file F;\n\
If F is - then read names from standard input\n\
- -L, --max-line-length print the length of the longest line\n\
+ -L, --max-line-length print the maximum display width\n\
-w, --words print the word counts\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -184,9 +190,10 @@ write_counts (uintmax_t lines,
/* Count words. FILE_X is the name of the file (or NULL for standard
input) that is open on descriptor FD. *FSTATUS is its status.
+ CURRENT_POS is the current file offset if known, negative if unknown.
Return true if successful. */
static bool
-wc (int fd, char const *file_x, struct fstatus *fstatus)
+wc (int fd, char const *file_x, struct fstatus *fstatus, off_t current_pos)
{
bool ok = true;
char buf[BUFFER_SIZE + 1];
@@ -229,42 +236,43 @@ wc (int fd, char const *file_x, struct fstatus *fstatus)
if (count_bytes && !count_chars && !print_lines && !count_complicated)
{
- off_t current_pos, end_pos;
-
if (0 < fstatus->failed)
fstatus->failed = fstat (fd, &fstatus->st);
- if (! fstatus->failed && S_ISREG (fstatus->st.st_mode)
- && (current_pos = lseek (fd, 0, SEEK_CUR)) != -1
- && (end_pos = lseek (fd, 0, SEEK_END)) != -1)
+ /* For sized files, seek to one st_blksize before EOF rather than to EOF.
+ This works better for files in proc-like file systems where
+ the size is only approximate. */
+ if (! fstatus->failed && usable_st_size (&fstatus->st)
+ && 0 <= fstatus->st.st_size)
{
- /* Be careful here. The current position may actually be
- beyond the end of the file. As in the example above. */
- bytes = end_pos < current_pos ? 0 : end_pos - current_pos;
+ size_t end_pos = fstatus->st.st_size;
+ off_t hi_pos = end_pos - end_pos % (ST_BLKSIZE (fstatus->st) + 1);
+ if (current_pos < 0)
+ current_pos = lseek (fd, 0, SEEK_CUR);
+ if (0 <= current_pos && current_pos < hi_pos
+ && 0 <= lseek (fd, hi_pos, SEEK_CUR))
+ bytes = hi_pos - current_pos;
}
- else
+
+ fdadvise (fd, 0, 0, FADVISE_SEQUENTIAL);
+ while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
{
- fdadvise (fd, 0, 0, FADVISE_SEQUENTIAL);
- while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
+ if (bytes_read == SAFE_READ_ERROR)
{
- if (bytes_read == SAFE_READ_ERROR)
- {
- error (0, errno, "%s", file);
- ok = false;
- break;
- }
- bytes += bytes_read;
+ error (0, errno, "%s", file);
+ ok = false;
+ break;
}
+ bytes += bytes_read;
}
}
else if (!count_chars && !count_complicated)
{
/* Use a separate loop when counting only lines or lines and bytes --
but not chars or words. */
+ bool long_lines = false;
while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
{
- char *p = buf;
-
if (bytes_read == SAFE_READ_ERROR)
{
error (0, errno, "%s", file);
@@ -272,12 +280,38 @@ wc (int fd, char const *file_x, struct fstatus *fstatus)
break;
}
- while ((p = memchr (p, '\n', (buf + bytes_read) - p)))
+ bytes += bytes_read;
+
+ char *p = buf;
+ char *end = p + bytes_read;
+ uintmax_t plines = lines;
+
+ if (! long_lines)
{
- ++p;
- ++lines;
+ /* Avoid function call overhead for shorter lines. */
+ while (p != end)
+ lines += *p++ == '\n';
}
- bytes += bytes_read;
+ else
+ {
+ /* memchr is more efficient with longer lines. */
+ while ((p = memchr (p, '\n', end - p)))
+ {
+ ++p;
+ ++lines;
+ }
+ }
+
+ /* If the average line length in the block is >= 15, then use
+ memchr for the next block, where system specific optimizations
+ may outweigh function call overhead.
+ FIXME: This line length was determined in 2015, on both
+ x86_64 and ppc64, but it's worth re-evaluating in future with
+ newer compilers, CPUs, or memchr() implementations etc. */
+ if (lines - plines <= bytes_read / 15)
+ long_lines = true;
+ else
+ long_lines = false;
}
}
#if MB_LEN_MAX > 1
@@ -500,7 +534,7 @@ wc_file (char const *file, struct fstatus *fstatus)
have_read_stdin = true;
if (O_BINARY && ! isatty (STDIN_FILENO))
xfreopen (NULL, "rb", stdin);
- return wc (STDIN_FILENO, file, fstatus);
+ return wc (STDIN_FILENO, file, fstatus, -1);
}
else
{
@@ -512,7 +546,7 @@ wc_file (char const *file, struct fstatus *fstatus)
}
else
{
- bool ok = wc (fd, file, fstatus);
+ bool ok = wc (fd, file, fstatus, 0);
if (close (fd) != 0)
{
error (0, errno, "%s", file);
@@ -530,7 +564,7 @@ wc_file (char const *file, struct fstatus *fstatus)
that happens when we don't know how long the list of file names will be. */
static struct fstatus *
-get_input_fstatus (int nfiles, char *const *file)
+get_input_fstatus (size_t nfiles, char *const *file)
{
struct fstatus *fstatus = xnmalloc (nfiles ? nfiles : 1, sizeof *fstatus);
@@ -542,7 +576,7 @@ get_input_fstatus (int nfiles, char *const *file)
fstatus[0].failed = 1;
else
{
- int i;
+ size_t i;
for (i = 0; i < nfiles; i++)
fstatus[i].failed = (! file[i] || STREQ (file[i], "-")
@@ -558,7 +592,7 @@ get_input_fstatus (int nfiles, char *const *file)
get_input_fstatus optimizes. */
static int _GL_ATTRIBUTE_PURE
-compute_number_width (int nfiles, struct fstatus const *fstatus)
+compute_number_width (size_t nfiles, struct fstatus const *fstatus)
{
int width = 1;
@@ -566,7 +600,7 @@ compute_number_width (int nfiles, struct fstatus const *fstatus)
{
int minimum_width = 1;
uintmax_t regular_total = 0;
- int i;
+ size_t i;
for (i = 0; i < nfiles; i++)
if (! fstatus[i].failed)
@@ -592,7 +626,7 @@ main (int argc, char **argv)
{
bool ok;
int optc;
- int nfiles;
+ size_t nfiles;
char **files;
char *files_from = NULL;
struct fstatus *fstatus;
@@ -797,5 +831,5 @@ main (int argc, char **argv)
if (have_read_stdin && close (STDIN_FILENO) != 0)
error (EXIT_FAILURE, errno, "-");
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/who.c b/src/who.c
index f07cee61..0a09411f 100644
--- a/src/who.c
+++ b/src/who.c
@@ -1,5 +1,5 @@
/* GNU's who.
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -582,8 +582,8 @@ scan_entries (size_t n, const STRUCT_UTMP *utmp_buf)
while (n--)
{
if (!my_line_only
- || strncmp (ttyname_b, utmp_buf->ut_line,
- sizeof (utmp_buf->ut_line)) == 0)
+ || STREQ_LEN (ttyname_b, utmp_buf->ut_line,
+ sizeof (utmp_buf->ut_line)))
{
if (need_users && IS_USER_PROCESS (utmp_buf))
print_user (utmp_buf, boottime);
@@ -675,7 +675,7 @@ Print information about users who are currently logged in.\n\
If FILE is not specified, use %s. %s as FILE is common.\n\
If ARG1 ARG2 given, -m presumed: 'am i' or 'mom likes' are usual.\n\
"), UTMP_FILE, WTMP_FILE);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -828,5 +828,5 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/whoami.c b/src/whoami.c
index 7301abb1..507910bb 100644
--- a/src/whoami.c
+++ b/src/whoami.c
@@ -1,6 +1,6 @@
/* whoami -- print effective userid
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -49,7 +49,7 @@ Same as id -un.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -83,12 +83,9 @@ main (int argc, char **argv)
errno = 0;
uid = geteuid ();
pw = (uid == NO_UID && errno ? NULL : getpwuid (uid));
- if (pw)
- {
- puts (pw->pw_name);
- exit (EXIT_SUCCESS);
- }
- fprintf (stderr, _("%s: cannot find name for user ID %lu\n"),
- program_name, (unsigned long int) uid);
- exit (EXIT_FAILURE);
+ if (!pw)
+ error (EXIT_FAILURE, errno, _("cannot find name for user ID %lu"),
+ (unsigned long int) uid);
+ puts (pw->pw_name);
+ return EXIT_SUCCESS;
}
diff --git a/src/yes.c b/src/yes.c
index 97213124..07885be9 100644
--- a/src/yes.c
+++ b/src/yes.c
@@ -1,5 +1,5 @@
/* yes - output a string repeatedly until killed
- Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ Copyright (C) 1991-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ Repeatedly output a line with all specified STRING(s), or 'y'.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_ancillary_info ();
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -58,6 +58,10 @@ Repeatedly output a line with all specified STRING(s), or 'y'.\n\
int
main (int argc, char **argv)
{
+ char buf[BUFSIZ];
+ char *pbuf = buf;
+ int i;
+
initialize_main (&argc, &argv);
set_program_name (argv[0]);
setlocale (LC_ALL, "");
@@ -77,12 +81,54 @@ main (int argc, char **argv)
argv[argc++] = bad_cast ("y");
}
- while (true)
+ /* Buffer data locally once, rather than having the
+ large overhead of stdio buffering each item. */
+ for (i = optind; i < argc; i++)
+ {
+ size_t len = strlen (argv[i]);
+ if (BUFSIZ < len || BUFSIZ - len <= pbuf - buf)
+ break;
+ memcpy (pbuf, argv[i], len);
+ pbuf += len;
+ *pbuf++ = i == argc - 1 ? '\n' : ' ';
+ }
+ if (i == argc)
+ {
+ size_t line_len = pbuf - buf;
+ size_t lines = BUFSIZ / line_len;
+ while (--lines)
+ {
+ memcpy (pbuf, pbuf - line_len, line_len);
+ pbuf += line_len;
+ }
+ }
+
+ /* The normal case is to continuously output the local buffer. */
+ while (i == argc)
+ {
+ if (write (STDOUT_FILENO, buf, pbuf - buf) == -1)
+ {
+ error (0, errno, _("standard output"));
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* If the data doesn't fit in BUFSIZ then output
+ what we've buffered, and iterate over the remaining items. */
+ while (true /* i != argc */)
{
- int i;
- for (i = optind; i < argc; i++)
- if (fputs (argv[i], stdout) == EOF
- || putchar (i == argc - 1 ? '\n' : ' ') == EOF)
- error (EXIT_FAILURE, errno, _("standard output"));
+ int j;
+ if ((pbuf - buf) && fwrite (buf, pbuf - buf, 1, stdout) != 1)
+ {
+ error (0, errno, _("standard output"));
+ return EXIT_FAILURE;
+ }
+ for (j = i; j < argc; j++)
+ if (fputs (argv[j], stdout) == EOF
+ || putchar (j == argc - 1 ? '\n' : ' ') == EOF)
+ {
+ error (0, errno, _("standard output"));
+ return EXIT_FAILURE;
+ }
}
}