Compare commits

...

223 Commits

Author SHA1 Message Date
Jim Meyering
8c8f0df4f0 [HAVE_INTTYPES_H]: Include <inttypes.h>. 2000-12-23 10:43:33 +00:00
Jim Meyering
69e09f0559 *** empty log message *** 2000-12-22 22:45:32 +00:00
Jim Meyering
1a18604b2e (isaac_seed_machdep) [_ARCH_PPC]: Disable the code
that would use the PPC mfspr `asm' code.
2000-12-22 22:44:30 +00:00
Jim Meyering
eae1c2b69c . 2000-12-19 11:06:05 +00:00
Jim Meyering
4c038111f8 *** empty log message *** 2000-12-19 10:51:39 +00:00
Jim Meyering
a82d4c2b3d . 2000-12-19 10:50:31 +00:00
Jim Meyering
0cba2d7f5b *** empty log message *** 2000-12-19 10:37:30 +00:00
Jim Meyering
a87ae161be . 2000-12-19 10:25:15 +00:00
Jim Meyering
275b1879c3 . 2000-12-19 10:25:15 +00:00
Jim Meyering
66cf2ad8ce *** empty log message *** 2000-12-19 09:23:47 +00:00
Jim Meyering
0966c0f860 . 2000-12-19 09:23:09 +00:00
Jim Meyering
83a6c55c74 (UINTMAX_MAX): New macro, taken from C99. 2000-12-19 09:22:24 +00:00
Jim Meyering
3c46adfe19 adjust indentation 2000-12-19 09:21:42 +00:00
Jim Meyering
0787040b75 *** empty log message *** 2000-12-19 09:16:39 +00:00
Jim Meyering
bf86c62a33 Include physmem.h.
(SORTALLOC, mergealloc, LINEALLOC): Remove.
(sortalloc): Default to zero at program startup.
(SORTALLOC_MIN, SORTALLOC_DEFAULT_MIN): New macros.
(usage, main): Add support for new -S SIZE option.
(specify_sort_size, default_sort_size): New functions.
(initlines): Do not let alloc exceed limit.
(findlines): Likewise.
(checkfp, mergefps, sort): Use sortalloc to size everything
else, instead of relying on precomputed sizes.
2000-12-19 09:16:28 +00:00
Jim Meyering
915dacbb85 New "sort" option -S SIZE. 2000-12-19 08:40:54 +00:00
Jim Meyering
b6b86da148 *** empty log message *** 2000-12-19 08:36:53 +00:00
Jim Meyering
de38d76a18 (libfetish_a_SOURCES): Add physmem.c.
(noinst_HEADERS): Add physmem.h.
2000-12-19 08:36:39 +00:00
Jim Meyering
166c00189a (__xstrtol): Add undocumented suffixes 'g' and
't' for compatibility with Solaris 8 sort.
2000-12-19 08:35:20 +00:00
Jim Meyering
bca787f7c4 *** empty log message *** 2000-12-19 08:22:18 +00:00
Jim Meyering
258f00968a *** empty log message *** 2000-12-19 08:16:25 +00:00
Jim Meyering
bc40f9fcef (locale_charset): Add support for Win32. 2000-12-19 08:16:09 +00:00
Jim Meyering
d81418fd5e . 2000-12-18 23:43:27 +00:00
Jim Meyering
85ab4b9988 *** empty log message *** 2000-12-18 23:04:34 +00:00
Jim Meyering
f75f8a4b1d Add support for BeOS. 2000-12-18 23:04:28 +00:00
Jim Meyering
dfada44550 these macros take arguments 2000-12-17 09:26:55 +00:00
Jim Meyering
5d4c822ef7 *** empty log message *** 2000-12-17 09:23:05 +00:00
Jim Meyering
55f51356fb (jm_AC_DOS): New file and macro. 2000-12-17 09:22:56 +00:00
Jim Meyering
3f6afc4a7a (jm_MACROS): Require jm_AC_DOS. 2000-12-17 09:22:17 +00:00
Jim Meyering
dc87bf344c *** empty log message *** 2000-12-17 00:19:05 +00:00
Jim Meyering
7a41a27413 *** empty log message *** 2000-12-17 00:18:50 +00:00
Jim Meyering
8dc25234e0 *** empty log message *** 2000-12-17 00:17:26 +00:00
Jim Meyering
24ad4ecf29 *** empty log message *** 2000-12-17 00:17:03 +00:00
Jim Meyering
c9f0363bea . 2000-12-17 00:15:02 +00:00
Jim Meyering
c44bd5683d Update from master repository. 2000-12-17 00:14:40 +00:00
Jim Meyering
ae8bf0e8f1 . 2000-12-16 23:35:38 +00:00
Jim Meyering
fbba4d8d5e *** empty log message *** 2000-12-16 22:27:18 +00:00
Jim Meyering
2b64713ac6 *** empty log message *** 2000-12-16 22:26:23 +00:00
Jim Meyering
2464a2cd9d [!SHELLS_FILE && __DJGPP__]: Define
SHELLS_FILE to a file name that's useful on djgpp systems.
Include stdlib.h.
(ADDITIONAL_DEFAULT_SHELLS): Define.
(default_shells): Prepend ADDITIONAL_DEFAULT_SHELLS.
Based mostly on a patch from Prashant TR.
2000-12-16 22:25:44 +00:00
Jim Meyering
96e6715ebe . 2000-12-16 18:53:08 +00:00
Jim Meyering
72d973cb61 (uint_to_string): New function.
(uid_to_name): Use it.
(gid_to_name): Use it.
Rename locals, user/group, to uid/gid.
2000-12-16 18:52:58 +00:00
Jim Meyering
39d300f12b (enum Change_status): Start with 1. 2000-12-16 18:47:43 +00:00
Jim Meyering
76f8538bf6 . 2000-12-16 14:49:25 +00:00
Jim Meyering
71411370e7 *** empty log message *** 2000-12-16 13:41:40 +00:00
Jim Meyering
eb24d1f55c *** empty log message *** 2000-12-16 13:40:37 +00:00
Jim Meyering
608b347584 This bug had a serious impact on chown: `chown N:M FILE' (for integer
N and M) would have treated it like `chown N:N FILE'.
(parse_user_spec): Fix typo: s/u/g/.
2000-12-16 13:28:13 +00:00
Jim Meyering
6c4cbe6b5f (main): Rename local, group, to gid. 2000-12-16 13:10:05 +00:00
Jim Meyering
ad31d9b60c tweak a comment 2000-12-16 13:01:24 +00:00
Jim Meyering
8e2ee9a689 (main): Rename locals, user/group, to uid/gid. 2000-12-16 12:57:14 +00:00
Jim Meyering
067af316b6 *** empty log message *** 2000-12-16 09:23:52 +00:00
Jim Meyering
c0ab7dc021 *** empty log message *** 2000-12-16 09:23:32 +00:00
Jim Meyering
8233adab59 Use group-names. 2000-12-16 09:23:10 +00:00
Jim Meyering
be74434bbd Use group-names. 2000-12-16 09:21:20 +00:00
Jim Meyering
bbc027cf8b *** empty log message *** 2000-12-16 09:19:34 +00:00
Jim Meyering
43da73f064 Don't assume that creating a file gives it group $g1. 2000-12-16 09:11:24 +00:00
Jim Meyering
ffc1ef87ea . 2000-12-16 08:20:57 +00:00
Jim Meyering
66e2135f07 (TESTS): Add recurse. 2000-12-16 08:20:11 +00:00
Jim Meyering
e6a5c51ed7 Add ISO-8859-3, BIG5HKSCS, GB18030, JOHAB, VISCII,
CP874, CP949, CP950, CP1250, CP1253, CP1254, CP1255, CP1256, CP1257
to the list of canonical encodings. Rename EUC-CN to GB2312.
2000-12-15 23:43:55 +00:00
Jim Meyering
d952853f74 *** empty log message *** 2000-12-15 14:49:48 +00:00
Jim Meyering
3ebf224b28 *** empty log message *** 2000-12-15 14:45:50 +00:00
Jim Meyering
9be2faa156 *** empty log message *** 2000-12-15 13:32:24 +00:00
Jim Meyering
a8fff5ee1f *** empty log message *** 2000-12-15 13:31:21 +00:00
Jim Meyering
4ab4534292 . 2000-12-15 13:30:32 +00:00
Jim Meyering
0e81b6b48e (main): Reflect renaming: s/dereference/change_symlinks/. 2000-12-15 13:29:56 +00:00
Jim Meyering
694c6b3a86 (enum Dereference_symlink): rename member: s/change_symlinks/dereference/ 2000-12-15 13:27:03 +00:00
Jim Meyering
9724aab7a6 Declare lstat.
Rename change_symlinks member to `dereference' and use the DEREF_*
enum values.
(describe_change): Merge the chgrp and chown switch statements.
Use xmalloc to form the `user:group' string.
(change_file_owner): Record (and later, use) is_symlink and is_directory
from the lstat stats, in order to control whether we operate on symlinks
and whether (with -R) we traverse symlinks to directories.
When dereferencing, use open/fchown (rather than chown) on symlinks.
2000-12-15 13:24:47 +00:00
Jim Meyering
b6ca14a123 changed messages to match those chgrp now produces 2000-12-15 08:42:35 +00:00
Jim Meyering
976f3796be *** empty log message *** 2000-12-14 15:01:55 +00:00
Jim Meyering
1c643649b0 *** empty log message *** 2000-12-14 15:01:24 +00:00
Jim Meyering
3337b5a092 *** empty log message *** 2000-12-14 14:52:15 +00:00
Jim Meyering
b41ab84baa *** empty log message *** 2000-12-13 22:25:42 +00:00
Jim Meyering
af996c06d0 *** empty log message *** 2000-12-13 07:54:44 +00:00
Jim Meyering
2a21b4cf40 *** empty log message *** 2000-12-10 23:25:43 +00:00
Jim Meyering
3614a52150 *** empty log message *** 2000-12-10 12:50:40 +00:00
Jim Meyering
d2be99eb17 add envvar and lang checks 2000-12-10 09:20:52 +00:00
Jim Meyering
fca6110993 *** empty log message *** 2000-12-10 09:20:35 +00:00
Jim Meyering
9bb0e5cdb7 *** empty log message *** 2000-12-10 08:07:38 +00:00
Jim Meyering
cf302e3bc9 give a better diagnostic when only the group is being changed 2000-12-10 08:04:50 +00:00
Jim Meyering
b50fed9980 . 2000-12-09 22:18:02 +00:00
Jim Meyering
baf047f89a *** empty log message *** 2000-12-09 22:17:31 +00:00
Jim Meyering
a65f9eef4a *** empty log message *** 2000-12-09 22:16:57 +00:00
Jim Meyering
9c149c3b6c . 2000-12-09 22:07:28 +00:00
Jim Meyering
d64368c699 *** empty log message *** 2000-12-09 22:06:03 +00:00
Jim Meyering
97e76d3e24 (jm_MACROS): Remove jm_SYS_OFF_T_PRINTF_FORMAT. 2000-12-09 22:05:54 +00:00
Jim Meyering
a157495002 . 2000-12-09 22:05:28 +00:00
Jim Meyering
3c805daf45 . 2000-12-09 20:55:41 +00:00
Jim Meyering
8f55fdc385 (chopt_free): don't free anything 2000-12-09 20:54:23 +00:00
Jim Meyering
26f88f15c8 *** empty log message *** 2000-12-09 20:44:39 +00:00
Jim Meyering
6820c8729e *** empty log message *** 2000-12-09 20:39:17 +00:00
Jim Meyering
78169b6a2f *** empty log message *** 2000-12-09 20:38:12 +00:00
Jim Meyering
5a795ec749 Include "chown-core.h".
[enum Change_status, enum Verbosity]: Remove declarations.
Remove decls of globals that are now part of struct Chown_option.
Remove decl of xstat.
(describe_change): Remove function.
(change_file_group): Likewise.
(change_dir_group): Likewise.
(parse_group): Don't set global, groupname, here...
(main): ... instead, initialize `chopt.group_name' here.
Initialize chopt and update uses of the now-members.
Set group_name also when it's obtained via a --reference=FILE option.
Call change_file_owner (with -1 for uids), not change_file_group.
2000-12-09 20:38:01 +00:00
Jim Meyering
d26ef4e978 add 3 more prototypes 2000-12-09 20:31:56 +00:00
Jim Meyering
40d911bc45 Include <pwd.h>, <grp.h>, and "xalloc.h".
[!_POSIX_VERSION]: Declare getgrnam and getgrgid.
(gid_to_name): New function.
(uid_to_name): Likewise.
(chopt_free): Likewise.
2000-12-09 20:31:34 +00:00
Jim Meyering
748db39d02 Don't include pwd.h or grp.h -- no longer needed.
Include chown-core.h.
[enum Change_status, enum Verbosity]: Remove declarations.
Remove decls of globals that are now part of struct Chown_option.
(describe_change): Remove function.
(change_file_owner): Likewise.
(change_dir_owner): Likewise.
(main): Initialize chopt and update uses of the now-members.
Set user_name and group_name also when they're obtained via a
--reference=FILE option.
Pass `chopt' to change_file_owner.
2000-12-09 20:29:32 +00:00
Jim Meyering
4db97b7a7d *** empty log message *** 2000-12-09 14:47:06 +00:00
Jim Meyering
f8b26d3ade *** empty log message *** 2000-12-09 14:46:34 +00:00
Jim Meyering
5c8eb8ec36 *** empty log message *** 2000-12-09 14:08:07 +00:00
Jim Meyering
64f7bff756 *** empty log message *** 2000-12-09 13:50:13 +00:00
Jim Meyering
040db4c3fe *** empty log message *** 2000-12-09 13:48:03 +00:00
Jim Meyering
34ef74b11c *** empty log message *** 2000-12-09 13:44:37 +00:00
Jim Meyering
de4a3dfb26 *** empty log message *** 2000-12-09 13:44:10 +00:00
Jim Meyering
108881a3b2 *** empty log message *** 2000-12-09 13:38:51 +00:00
Jim Meyering
7d5f893b7f *** empty log message *** 2000-12-09 12:47:51 +00:00
Jim Meyering
8d977c3978 *** empty log message *** 2000-12-09 10:15:26 +00:00
Jim Meyering
73f1bc31d7 (change_file_owner): Restore special file permission
bits, since calling chown resets them on some systems.
Reported by Matt Perry.
2000-12-09 10:15:17 +00:00
Jim Meyering
497d1d9e97 *** empty log message *** 2000-12-09 10:14:52 +00:00
Jim Meyering
764dd3149e Don't make the success of the test depend
on the order in which directory entries are processed.
2000-12-08 20:31:47 +00:00
Jim Meyering
b2b9bed164 *** empty log message *** 2000-12-08 20:31:15 +00:00
Jim Meyering
9580e7cc87 *** empty log message *** 2000-12-08 18:32:11 +00:00
Jim Meyering
a05267197a (mbsnwidth): Don't loop endlessly when called with an
invalid mulitbyte sequence and with the MBSW_ACCEPT_INVALID flag set.
2000-12-08 18:31:38 +00:00
Jim Meyering
a90e5f5a69 *** empty log message *** 2000-12-08 08:06:33 +00:00
Jim Meyering
1f47a082c4 Include xalloc.h.
(main): Use dir_name rather than the underlying dir_name_r.
The former now handles cwd-relative names with drive-letter prefixes.
2000-12-08 07:55:05 +00:00
Jim Meyering
7b55b7aa13 *** empty log message *** 2000-12-07 14:14:18 +00:00
Jim Meyering
bcc94017bc convert a > expression to the equivalent < one 2000-12-07 14:13:51 +00:00
Jim Meyering
b615d79ac3 (ISSLASH): Define.
(strip_trailing_slashes): Use ISSLASH rather than comparing against `/'.
From Prashant TR.
2000-12-07 14:13:13 +00:00
Jim Meyering
04f549820f convert a > expression to the equivalent < one 2000-12-07 14:11:52 +00:00
Jim Meyering
ded8b14afb *** empty log message *** 2000-12-07 14:10:33 +00:00
Jim Meyering
4504b81f3b (FILESYSTEM_PREFIX_LEN): Define.
(dir_name_r): Declare this function as static.
[BACKSLASH_IS_PATH_SEPARATOR]: Fix a bug that'd
manifest itself on a name containing a mix of slashes and
backslashes.
Make this function work with names starting with a DOS-style
drive letter and colon prefix.
(dir_name): Append `.' if necessary.
Based mostly on patches from Prashant TR and Eli Zaretskii.
2000-12-07 14:10:21 +00:00
Jim Meyering
222412dbf1 (dir_name_r): Remove prototype. 2000-12-07 11:50:35 +00:00
Jim Meyering
71751f757d *** empty log message *** 2000-12-07 10:07:28 +00:00
Jim Meyering
8c8424d0c2 (address_base): Declare to be static. 2000-12-07 10:07:08 +00:00
Jim Meyering
e42f27d147 (address_base, address_pad_len): New var.
(output_address_fmt_string, address_fmt_buffer, address_pad): Remove.
(flag_pseudo_start): Now int, not long int.
(pseudo_offset): Now off_t, not long int.
(n_specs, n_specs_allocated): Now size_t, not unsigned int.
(format_address, format_address_none, format_address_std,
format_address_label): Now accepts an extra char argument (an extra
char to print if nonzero), and prints instead of returning a string.
All callers changed.
(bytes_per_block): Now size_t, not int.
(format_address_none): Do not even print the extra char argument.
This simplifies the callers.
(format_address_std, format_address_label): Print off_t ourself
instead of trying to use autoconfigured format.  This is faster and
more portable.
(format_address_paren): New function.
(dump): Remove unnecessary cast.
(expand_address_fmt): Remove.
(main): Use size_t, off_t, etc. instead of builtin types where this is
advisable.  Adjust to above changes.  Remove unnecessary cast.
2000-12-07 10:05:09 +00:00
Jim Meyering
d1cca1ee9c *** empty log message *** 2000-12-06 11:06:43 +00:00
Jim Meyering
0654f3206d Check for strtol. Mainly as a cue to cause automake to include
strtol.c -- that file is included by each of strtoul.c and strtoull.c.
Check for limits.h -- strtol.c needs it.
2000-12-06 11:06:39 +00:00
Jim Meyering
67cf94a857 *** empty log message *** 2000-12-06 10:52:37 +00:00
Jim Meyering
69ed54e544 Check for declarations of strtoul and strtoull. 2000-12-06 10:52:28 +00:00
Jim Meyering
3dabe6b533 separate conditions for strtoul and strtoull 2000-12-06 10:26:51 +00:00
Jim Meyering
2845214164 *** empty log message *** 2000-12-06 09:55:03 +00:00
Jim Meyering
6b8102a180 *** empty log message *** 2000-12-06 09:35:48 +00:00
Jim Meyering
570074d6d1 (jm_AC_PREREQ_XSTRTOUMAX): If we need the replacement
strtoull, we may well need the replacement strtoul, too.
2000-12-06 09:35:40 +00:00
Jim Meyering
72a6d74ab2 . 2000-12-05 13:53:13 +00:00
Jim Meyering
cd6f0af0ea (dir_name_r): Add `const' in a few local declarations. 2000-12-05 13:14:13 +00:00
Jim Meyering
2746cd50c3 *** empty log message *** 2000-12-04 09:41:28 +00:00
Jim Meyering
8a4261c7a5 *** empty log message *** 2000-12-04 09:37:40 +00:00
Jim Meyering
90799b6c68 Also include memory.h, stdlib.h, unistd.h if appropriate. 2000-12-04 09:37:33 +00:00
Jim Meyering
1c6320fe7c *** empty log message *** 2000-12-04 09:15:54 +00:00
Jim Meyering
fecdd2bd2b [!HAVE_DECL_MALLOC]: Declare malloc. 2000-12-04 09:15:49 +00:00
Jim Meyering
15691fb64f *** empty log message *** 2000-12-03 22:40:40 +00:00
Jim Meyering
cb366955f3 (gobble_file) [USE_ACL]: Set have_acl member unconditionally
to avoid uninitialized memory reference via FILE_HAS_ACL.
2000-12-03 22:40:31 +00:00
Jim Meyering
82a6fbda1c *** empty log message *** 2000-12-03 20:46:07 +00:00
Jim Meyering
177b2553e2 (TESTS): Add assert-2. 2000-12-03 20:43:51 +00:00
Jim Meyering
814e63e371 remove instrumentation 2000-12-03 20:37:55 +00:00
Jim Meyering
2eed25f2ed add instrumentation to detect some UMRs 2000-12-03 20:37:18 +00:00
Jim Meyering
1be9e19c7d *** empty log message *** 2000-12-03 20:36:29 +00:00
Jim Meyering
b7895d0d10 (tail_file): Initialize ignore, dev, and ino members,
when tailing forever and the open failed.  Otherwise, we could get
uninitialized memory references of those fields in recheck.
2000-12-03 20:36:19 +00:00
Jim Meyering
8461820956 *** empty log message *** 2000-12-03 13:10:48 +00:00
Jim Meyering
86960ce221 *** empty log message *** 2000-12-03 12:46:55 +00:00
Jim Meyering
6670163eee (alpha): Use rsync rather than scp, so the destination
file is created only after the successful completion of the copy.
2000-12-03 12:46:44 +00:00
Jim Meyering
437f8becaa . 2000-12-03 12:31:59 +00:00
Jim Meyering
5233121102 use CHAR_BIT, not BITSPERBYTE 2000-12-03 11:00:06 +00:00
Jim Meyering
25c2989d30 *** empty log message *** 2000-12-03 10:59:49 +00:00
Jim Meyering
4f96dfa43e (CHAR_BIT): Define. 2000-12-03 10:59:44 +00:00
Jim Meyering
f559a4afa3 *** empty log message *** 2000-12-03 10:39:03 +00:00
Jim Meyering
b5d4b2c555 *** empty log message *** 2000-12-03 10:22:32 +00:00
Jim Meyering
d8a157a00e *** empty log message *** 2000-12-03 10:21:34 +00:00
Jim Meyering
85a75d3a16 *** empty log message *** 2000-12-03 10:18:09 +00:00
Jim Meyering
d183ecddcd Make od print valid addresses for offsets of 2^32 and larger. (cont'd)
(MAX_ADDRESS_LENGTH): Don't hard-code as a literal.
Rather, define in terms of the type, off_t.
(string_min): Declare to be of type size_t.
(flag_dump_strings): Declare to be of type int.
(print_s_char): Declare the n_bytes parameter and the local, `i',
to be of type off_t.
(print_char): Likewise.
(print_s_short): Likewise.
(print_short): Likewise.
(print_int): Likewise.
(print_long): Likewise.
(print_long_long): Likewise.
(print_float): Likewise.
(print_double): Likewise.
(print_long_double): Likewise.
(dump_hexl_mode_trailer): Likewise.
(print_named_ascii): Likewise.
(print_ascii): Likewise.
(write_block): Likewise.
(print_ascii): Declare local, `print_function' with a prototype.
Change a few `>' comparisons to the equivalent `<' form.
(parse_options): Declare `tmp' to be of type uintmax_t.
Use xstrtoumax, not xstrtoul.
Fail if the specified offset if larger than OFF_T_MAX.
(dump_strings): Declare local `i' to be of type size_t.
Remove the now-unnecessary cast-to-off_t.
(main) [IF_LINT]: Initialize desired_width to avoid a warning.
Declare `tmp' to be of type uintmax_t.
Use xstrtoumax, not xstrtoul.
Fail if minimum string length is larger than SIZE_MAX.
Fail if specified width is larger than ULONG_MAX.
2000-12-03 10:18:04 +00:00
Jim Meyering
e30c09b4cb Add this:
AC_REQUIRE([AC_TYPE_OFF_T])
2000-12-03 10:04:30 +00:00
Jim Meyering
9d5d7f0d50 (OFF_T_MIN): Remove definition.
(OFF_T_MAX): Likewise.
2000-12-03 08:55:51 +00:00
Jim Meyering
caae4ed5a7 (OFF_T_MIN): Define.
(OFF_T_MAX): Define.
2000-12-03 08:54:37 +00:00
Jim Meyering
a1ca60f4e5 Make od print valid addresses for offsets of 2^32 and larger.
(format_address): Use off_t, not long unsigned_int as the
parameter type.
(format_address_none): Likewise.  Mark parameter as unused.
(format_address_std): Likewise.
(format_address_label): Likewise.
(print_ascii): Mark format string parameter as unused.
(write_block): Use off_t, not long unsigned_int as offset type.
(expand_address_fmt): New function.
(main): Use it to expand each address format string template.
Reported by Mark Nudelman, via Andreas Jaeger.
2000-12-03 08:44:12 +00:00
Jim Meyering
ce861b2cb3 (parse_options): Use xstrtoumax to parse the byte and line
offset.  Give a better diagnostic when the requested offset is still
representable but larger than OFF_T_MAX.
2000-12-03 08:35:48 +00:00
Jim Meyering
67ec78d188 *** empty log message *** 2000-12-02 22:18:29 +00:00
Jim Meyering
d661be38ed (valid_format): Move pre-increment to a separate statement to avoid a warning. 2000-12-02 22:18:21 +00:00
Jim Meyering
69e30c7f2a Move dcls of globals used only in main...
(main): ...to here.
(usage): Clarify option descriptions.
2000-12-02 22:16:41 +00:00
Jim Meyering
8973e2b38c whoops. rename the use, too -- not just the decl!! 2000-12-02 21:14:41 +00:00
Jim Meyering
df52f23ebf *** empty log message *** 2000-12-02 21:14:09 +00:00
Jim Meyering
5edc91fc05 (checkfp): Rename local `buf' to avoid shadowing previous declaration. 2000-12-02 21:14:02 +00:00
Jim Meyering
8b4ac20908 (skip): Use lseek instead of worrying about fseeko or fseek.
This should be portable, as we seek before doing any I/O.
(fseeko): Remove; no longer used.
2000-12-02 21:08:01 +00:00
Jim Meyering
1a0d9ea086 add back the parens Paul removed :-) 2000-12-02 20:55:25 +00:00
Jim Meyering
e49511faef (gobble_file): Do not fall back on lstat if stat
fails; POSIX.2 does not allow this.  Invoke acl only on
non-symlinks, and only if lstat or stat succeeds.
2000-12-02 20:55:02 +00:00
Jim Meyering
e05c32a868 *** empty log message *** 2000-12-02 20:52:09 +00:00
Jim Meyering
c2f898236f *** empty log message *** 2000-12-02 20:45:40 +00:00
Jim Meyering
501ebc1cba Make idempotent, to avoid some obscure warnings. 2000-12-02 20:45:30 +00:00
Jim Meyering
77182607c0 . 2000-12-02 18:52:17 +00:00
Jim Meyering
6769657fa3 *** empty log message *** 2000-12-02 18:52:03 +00:00
Jim Meyering
dab453378b (OFF_T_PRINTF_FORMAT_STRING): require it. 2000-12-02 18:51:26 +00:00
Jim Meyering
aa266c29eb *** empty log message *** 2000-12-02 18:04:19 +00:00
Jim Meyering
6b94589fa4 *** empty log message *** 2000-12-02 18:02:05 +00:00
Jim Meyering
0d849addb3 *** empty log message *** 2000-12-02 17:44:04 +00:00
Jim Meyering
1698b85090 *** empty log message *** 2000-12-02 17:40:26 +00:00
Jim Meyering
a538ba0149 *** empty log message *** 2000-12-02 17:39:59 +00:00
Jim Meyering
41f20fd38f *** empty log message *** 2000-12-02 14:53:18 +00:00
Jim Meyering
1c8189de61 (TESTS): Add follow-slink. 2000-12-02 14:53:07 +00:00
Jim Meyering
525e76fce0 *** empty log message *** 2000-12-02 14:52:45 +00:00
Jim Meyering
d91624bd99 *** empty log message *** 2000-12-02 14:43:34 +00:00
Jim Meyering
1c71127370 (NONZERO): Define and use it to make the code a tiny
bit more readable.
2000-12-02 14:43:28 +00:00
Jim Meyering
4f1553c89f *** empty log message *** 2000-12-02 14:28:23 +00:00
Jim Meyering
1b9cb7ea23 (sort invocation): Clarify how -t works when
a sort key specifies a range of fields.  From Karl O. Pinc.
2000-12-02 14:28:11 +00:00
Jim Meyering
479aba180c *** empty log message *** 2000-12-02 14:10:37 +00:00
Jim Meyering
8eeae63a74 . 2000-12-02 14:04:05 +00:00
Jim Meyering
07584e33ec add test that would fail on NetBSD before the last change 2000-12-02 14:02:34 +00:00
Jim Meyering
33ba435db5 *** empty log message *** 2000-12-02 13:22:57 +00:00
Jim Meyering
73fe66c783 *** empty log message *** 2000-12-02 13:22:14 +00:00
Jim Meyering
cc27b86c60 (main): Remove any trailing slash unconditionally.
Reported by Volker Borchert.
2000-12-02 13:20:37 +00:00
Jim Meyering
9db47bb808 *** empty log message *** 2000-12-02 12:15:00 +00:00
Jim Meyering
8bf3961df0 *** empty log message *** 2000-12-02 12:05:15 +00:00
Jim Meyering
df7d583cc2 (TESTS): Add skip-seek2 2000-12-02 12:05:03 +00:00
Jim Meyering
271e41850b *** empty log message *** 2000-12-02 12:04:32 +00:00
Jim Meyering
97b58344c5 *** empty log message *** 2000-12-02 09:58:43 +00:00
Jim Meyering
627dac6c07 Include <config.h> before any system include file. 2000-12-02 09:58:31 +00:00
Jim Meyering
0742bc284e *** empty log message *** 2000-12-02 08:19:31 +00:00
Jim Meyering
acca4638b8 (skip, dd_copy): Use ssize_t to store result of
safe_read, to avoid overflow e.g. on 64-bit Solaris sparc.
(dd_copy): Remove unnecessary cast.
2000-12-02 08:19:21 +00:00
Jim Meyering
05aabec021 *** empty log message *** 2000-12-02 08:14:33 +00:00
Jim Meyering
e996c1bd77 Undo most of the changes since 2000-11-24, since we've
documented a standard way to do it.
(skip_bytes, seek_bytes): Remove.
(usage): Remove B suffix.
(scanargs, skip, dd_copy, main): Remove support for B suffix.
2000-12-02 08:12:56 +00:00
Jim Meyering
b529a77be8 *** empty log message *** 2000-11-30 20:36:08 +00:00
Jim Meyering
4faf0a9a17 *** empty log message *** 2000-11-30 20:35:02 +00:00
Jim Meyering
3e50cea2f5 (jm_MACROS): Add stdint.h to the list of headers. 2000-11-30 20:34:23 +00:00
Jim Meyering
339738f351 s/SIZE_T_MAX/SIZE_MAX/. 2000-11-30 20:30:04 +00:00
Jim Meyering
a48a4d5c63 Include <stdint.h> if HAVE_STDINT_H.
(SIZE_MAX): Renamed from SIZE_T_MAX, as C99 uses SIZE_MAX.
All uses changed.
2000-11-30 20:27:49 +00:00
Jim Meyering
57a0382b5f *** empty log message *** 2000-11-30 11:39:19 +00:00
Jim Meyering
835a8fa634 (SIZE_T_MAX): Define. 2000-11-30 11:39:08 +00:00
Jim Meyering
4ff7ab63ab *** empty log message *** 2000-11-30 11:33:57 +00:00
Jim Meyering
d92f4ac85e Port GNU "sort" to hosts where sizes don't fit in "int",
e.g. 64-bit Solaris (sparc).

("human.h", "xstrtol.h"): Include.
(struct line): length member is now size_t, not int.
(struct lines): Likewise for used, alloc, limit members.
(struct buffer): Likewise for used, alloc, left, newline_free members.
(struct keyfield): Likewise for sword, schar, eword, echar members.
(sortalloc, mergealloc, linelength): Now size_t, not int.

(initbuf, fillbuf, initlines, begfield, limfield, findlines,
numcompare, getmonth, keycompare, compare, checkfp, mergefps,
sortlines, sort): Accept, return, and use size_t for sizes, not int.

(fillbuf, initlines, findlines, checkfp, sort): Check for overflow
when computing buffer sizes.

(begfield, limfield): Do not index past end of array.

(checkfp): Return a boolean, not a line number, as the line
number may not fit in int.  All callers changed.  Use
uintmax_t for line numbers, not int.

(sort): Don't allocate tmp until we need it (and know the right size).

(parse_field_count): New function.

(main): Use it to check for overflow in field counts.
"outfile" is now a pointer to const.
2000-11-30 11:33:49 +00:00
Jim Meyering
21b8c52ae9 *** empty log message *** 2000-11-30 09:36:04 +00:00
Jim Meyering
7303ca25db (dir_name_r): Fix typo: int -> size_t. 2000-11-30 09:35:52 +00:00
Jim Meyering
060fb58f86 *** empty log message *** 2000-11-30 07:45:38 +00:00
Jim Meyering
d185a442b9 s/ifval/m4_ifval/ to accommodate new autoconf. 2000-11-30 07:44:58 +00:00
Jim Meyering
86046cb32f . 2000-11-30 07:40:16 +00:00
Jim Meyering
1500316caf remove useless parens 2000-11-27 09:33:53 +00:00
Jim Meyering
72454050bb *** empty log message *** 2000-11-27 09:04:38 +00:00
Jim Meyering
b0b9c6fee7 *** empty log message *** 2000-11-27 08:47:13 +00:00
Jim Meyering
4a9feba665 add an echo 2000-11-27 08:45:46 +00:00
68 changed files with 2751 additions and 1018 deletions

View File

@@ -121,6 +121,7 @@ announcement: NEWS ChangeLog $(distdir).tar.gz
for url in $(url_dir_list); do \
echo " $$url/$(xd-delta)"; \
done; \
echo; \
echo "Here are the MD5 and SHA1 signatures for the .tar.gz file"; \
echo; \
echo "$(md5) $(distdir).tar.gz"; \
@@ -171,7 +172,7 @@ alpha: writable-files po-check
cvs ci -m. $(prev_version_file)
@echo =====================================
@echo =====================================
@echo 'scp $(xd-delta) $(distdir).tar.gz \'
@echo 'rsync -e ssh --pro -av $(xd-delta) $(distdir).tar.gz \'
@echo ' $(b_host):$(b_real_dir)'
@echo '# send the /tmp/announcement e-mail'
@echo =====================================

2
THANKS
View File

@@ -186,6 +186,7 @@ Mark D. Roth roth@uiuc.edu
Mark Harris mark@monitor.designacc.com
Mark Hewitt mhewitt@armature.com
Mark Kettenis kettenis@phys.uva.nl
Mark Nudelman marknu@flash.net
Mark W. Eichin eichin@cygnus.com
Markus Demleitner msdemlei@auriga.ari.uni-heidelberg.de
Martin martin@dresden.nacamar.de
@@ -197,6 +198,7 @@ Marty Leisner leisner@sdsp.mc.xerox.com
Masami Takikawa takikawm@CS.ORST.EDU
Mate Wierdl mw@moni.msci.memphis.edu
Matej Vela mvela@public.srce.hr
Matt Perry matt@primefactor.com
Matthew Braun matthew@ans.net
Matthew Clarke Matthew_Clarke@mindlink.bc.ca
Matthew S. Levine mslevine@theory.lcs.mit.edu

View File

@@ -3,7 +3,7 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
\def\texinfoversion{2000-11-09.08}
\def\texinfoversion{2000-12-11.07}
%
% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
% Free Software Foundation, Inc.
@@ -704,20 +704,35 @@ where each line of input produces a line of output.}
% if you have multiple lines of stuff to put here, you'll need to
% make the vbox yourself of the appropriate size.
\ifx#1l%
\llap{#2\hskip\inmarginspacing}%
\llap{\ignorespaces #2\hskip\inmarginspacing}%
\else
\rlap{\hskip\hsize\hskip\inmarginspacing#2}%
\rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
\fi
\null
}%
}}
\def\inleftmargin{\doinmargin l}
\def\inrightmargin{\doinmargin r}
\def\inmargin{% not perfect, but better than nothing.
\ifodd\pageno
\let\temp=\inleftmargin
%
% @inmargin{TEXT [, RIGHT-TEXT]}
% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
% else use TEXT for both).
%
\def\inmargin#1{\parseinmargin #1,,\finish}
\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
\setbox0 = \hbox{\ignorespaces #2}%
\ifdim\wd0 > 0pt
\def\lefttext{#1}% have both texts
\def\righttext{#2}%
\else
\let\temp=\inrightmargin
\def\lefttext{#1}% have only one text
\def\righttext{#1}%
\fi
%
\ifodd\pageno
\def\temp{\inleftmargin\lefttext}%
\else
\def\temp{\inrightmargin\righttext}%
\fi
\temp
}
@@ -4304,6 +4319,7 @@ width0pt\relax} \fi
\gobble
}
% @quotation does normal linebreaking (hence we can't use \nonfillstart)
% and narrows the margins.
%
@@ -4326,6 +4342,158 @@ width0pt\relax} \fi
}
% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
% If we want to allow any <char> as delimiter,
% we need the curly braces so that makeinfo sees the @verb command, eg:
% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
%
% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
%
% [Knuth] p. 344; only we need to do '@' too
\def\dospecials{%
\do\ \do\\\do\@\do\{\do\}\do\$\do\&%
\do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~}
%
% [Knuth] p. 380
\def\uncatcodespecials{%
\def\do##1{\catcode`##1=12}\dospecials}
%
% [Knuth] pp. 380,381,391
% Disable Spanish ligatures ?` and !` of \tt font
\begingroup
\catcode`\`=\active\gdef`{\relax\lq}
\endgroup
%
% Setup for the @verb command.
%
% Eight spaces for a tab
\begingroup
\catcode`\^^I=\active
\gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
\endgroup
%
\def\setupverb{%
\tt % easiest (and conventionally used) font for verbatim
\def\par{\leavevmode\endgraf}%
\catcode`\`=\active
\tabeightspaces
% Respect line breaks,
% print special symbols as themselves, and
% make each space count
% must do in this order:
\obeylines \uncatcodespecials \sepspaces
}
% Setup for the @verbatim environment
%
% Real tab expansion
\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
%
\def\starttabbox{\setbox0=\hbox\bgroup}
\begingroup
\catcode`\^^I=\active
\gdef\tabexpand{%
\catcode`\^^I=\active
\def^^I{\leavevmode\egroup
\dimen0=\wd0 % the width so far, or since the previous tab
\divide\dimen0 by\tabw
\multiply\dimen0 by\tabw % compute previous multiple of \tabw
\advance\dimen0 by\tabw % advance to next multiple of \tabw
\wd0=\dimen0 \box0 \starttabbox
}%
}
\endgroup
\def\setupverbatim{%
% Easiest (and conventionally used) font for verbatim
\tt
\def\par{\leavevmode\egroup\box0\endgraf}%
\catcode`\`=\active
\tabexpand
% Respect line breaks,
% print special symbols as themselves, and
% make each space count
% must do in this order:
\obeylines \uncatcodespecials \sepspaces
\everypar{\starttabbox}%
}
% Do the @verb magic: verbatim text is quoted by unique
% delimiter characters. Before first delimiter expect a
% right brace, after last delimiter expect closing brace:
%
% \def\doverb'{'<char>#1<char>'}'{#1}
%
% [Knuth] p. 382; only eat outer {}
\begingroup
\catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12
\gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
\endgroup
%
\def\verb{\begingroup\setupverb\doverb}
%
%
% Do the @verbatim magic: define the macro \doverbatim so that
% the (first) argument ends when '@end verbatim' is reached, ie:
%
% \def\doverbatim#1@end verbatim{#1}
%
% For Texinfo it's a lot easier than for LaTeX,
% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
% we need not redefine '\', '{' and '}'
%
% Inspired by LaTeX's verbatim command set [latex.ltx]
%% Include LaTeX hack for completeness -- never know
%% \begingroup
%% \catcode`|=0 \catcode`[=1
%% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active
%% \catcode`\\=12|gdef|doverbatim#1@end verbatim[
%% #1|endgroup|def|Everbatim[]|end[verbatim]]
%% |endgroup
\begingroup
\catcode`\ =\active
\gdef\doverbatim#1@end verbatim{#1\end{verbatim}}
\endgroup
%
\def\verbatim{%
\def\Everbatim{\nonfillfinish\endgroup}%
\begingroup
\nonfillstart
\advance\leftskip by -\defbodyindent
\begingroup\setupverbatim\doverbatim
}
% @verbatiminclude FILE - insert text of file in verbatim environment.
%
% Allow normal characters that we make active in the argument (a file name).
\def\verbatiminclude{%
\begingroup
\catcode`\\=12
\catcode`~=12
\catcode`^=12
\catcode`_=12
\catcode`|=12
\catcode`<=12
\catcode`>=12
\catcode`+=12
\parsearg\doverbatiminclude
}
\def\setupverbatiminclude{%
\begingroup
\nonfillstart
\advance\leftskip by -\defbodyindent
\begingroup\setupverbatim
}
%
\def\doverbatiminclude#1{%
% Restore active chars for included file.
\endgroup
\begingroup
\def\thisfile{#1}%
\expandafter\expandafter\setupverbatiminclude\input\thisfile
\endgroup\nonfillfinish\endgroup
}
\message{defuns,}
% @defun etc.

View File

@@ -2260,6 +2260,24 @@ If @var{output-file} is one of the input files, @code{sort} copies
it to a temporary file before sorting and writing the output to
@var{output-file}.
@item -S @var{size}
@opindex -S
@cindex size for main memory sorting
Use a main-memory sort buffer of the given @var{size}. By default,
@var{size} is in units of 1,024 bytes. Appending @samp{%} causes
@var{size} to be interpreted as a percentage of physical memory.
Appending @samp{k} multiplies @var{size} by 1,024 (the default),
@samp{M} by 1,048,576, @samp{G} by 1,073,741,824, and so on for
@samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}. Appending
@samp{b} causes @var{size} to be interpreted as a byte count, with no
multiplication.
This option can improve the performance of @command{sort} by causing it
to start with a larger or smaller sort buffer than the default.
However, this option affects only the initial buffer size. The buffer
grows beyond @var{size} if @command{sort} encounters input lines larger
than @var{size}.
@item -t @var{separator}
@opindex -t
@cindex field separator character
@@ -2269,7 +2287,9 @@ string between a non-whitespace character and a whitespace character.
That is, given the input line @w{@samp{ foo bar}}, @code{sort} breaks it
into fields @w{@samp{ foo}} and @w{@samp{ bar}}. The field separator is
not considered to be part of either the field preceding or the field
following.
following. But note that sort fields that extend to the end of the line,
as @samp{-k 2}, or sort fields consisting of a range, as @samp{-k 2,3},
retain the field separators present between the endpoints of the range.
@item -T @var{tempdir}
@opindex -T

View File

@@ -1,3 +1,88 @@
2000-10-31 Bruno Haible <haible@clisp.cons.org>
* localcharset.c (locale_charset): Add support for Win32.
2000-12-18 Paul Eggert <eggert@twinsun.com>
* physmem.h, physmem.c: New files.
* Makefile.am (libfetish_a_SOURCES): Add physmem.c.
(noinst_HEADERS): Add physmem.h.
* xstrtol.c (__xstrtol): Add undocumented suffixes 'g' and
't' for compatibility with Solaris 8 sort.
2000-12-18 Bruno Haible <haible@clisp.cons.org>
* config.charset: Add support for BeOS.
2000-12-16 Jim Meyering <meyering@lucent.com>
* getusershell.c [!SHELLS_FILE && __DJGPP__]: Define
SHELLS_FILE to a file name that's useful on djgpp systems.
Include stdlib.h.
(ADDITIONAL_DEFAULT_SHELLS): Define.
(default_shells): Prepend ADDITIONAL_DEFAULT_SHELLS.
Based mostly on a patch from Prashant TR.
2000-12-16 Jim Meyering <meyering@lucent.com>
This bug had a serious impact on chown: `chown N:M FILE' (for integer
N and M) would have treated it like `chown N:N FILE'.
* userspec.c (parse_user_spec): Fix typo: s/u/g/.
2000-10-31 Bruno Haible <haible@clisp.cons.org>
* config.charset: Add ISO-8859-3, BIG5HKSCS, GB18030, JOHAB, VISCII,
CP874, CP949, CP950, CP1250, CP1253, CP1254, CP1255, CP1256, CP1257
to the list of canonical encodings. Rename EUC-CN to GB2312.
2000-12-08 Andreas Schwab <schwab@suse.de>
* mbswidth.c (mbsnwidth): Don't loop endlessly when called with an
invalid mulitbyte sequence and with the MBSW_ACCEPT_INVALID flag set.
2000-12-07 Jim Meyering <meyering@lucent.com>
* stripslash.c (ISSLASH): Define.
(strip_trailing_slashes): Use ISSLASH rather than comparing against `/'.
From Prashant TR.
* dirname.c (FILESYSTEM_PREFIX_LEN): Define.
(dir_name_r): Declare this function as static.
[BACKSLASH_IS_PATH_SEPARATOR]: Fix a bug that'd
manifest itself on a name containing a mix of slashes and
backslashes.
Make this function work with names starting with a DOS-style
drive letter and colon prefix.
(dir_name): Append `.' if necessary.
Based mostly on patches from Prashant TR and Eli Zaretskii.
* dirname.h (dir_name_r): Remove prototype.
2000-12-05 Jim Meyering <meyering@lucent.com>
* dirname.c (dir_name_r): Add `const' in a few local declarations.
2000-12-04 Jim Meyering <meyering@lucent.com>
* path-concat.c: [!HAVE_DECL_MALLOC]: Declare malloc.
Also include memory.h, stdlib.h, unistd.h if appropriate.
Reported by Andreas Jaeger (conflicting declaration of malloc).
2000-12-02 Jim Meyering <meyering@lucent.com>
* closeout.h: Make idempotent, to avoid some obscure warnings.
2000-12-01 Paul Eggert <eggert@twinsun.com>
* lib/memrchr.c: Include <config.h> before any system include file.
2000-11-29 Paul Eggert <eggert@twinsun.com>
* lib/dirname.c (dir_name_r): Fix typo: int -> size_t.
2000-11-26 Jim Meyering <meyering@lucent.com>
* memcoll.c: Include sys/types.h. From Werner Almesberger.

View File

@@ -13,7 +13,7 @@ libfetish_a_SOURCES = \
full-write.c getopt.c getopt1.c getstr.c getugroups.c hard-locale.c hash.c \
human.c idcache.c isdir.c linebuffer.c localcharset.c long-options.c \
makepath.c mbswidth.c md5.c memcasecmp.c memcoll.c modechange.c \
path-concat.c \
path-concat.c physmem.c \
quote.c quotearg.c readtokens.c safe-read.c same.c save-cwd.c \
savedir.c sha.c stripslash.c unicodeio.c userspec.c version-etc.c xgetcwd.c \
xgethostname.c xmalloc.c xstrdup.c xstrtod.c xstrtol.c xstrtoul.c \
@@ -29,7 +29,8 @@ noinst_HEADERS = \
getstr.h getpagesize.h group-member.h hard-locale.h hash.h human.h lchown.h \
linebuffer.h long-options.h mbswidth.h md5.h memcasecmp.h memcoll.h \
makepath.h mbswidth.h modechange.h mountlist.h nanosleep.h obstack.h \
path-concat.h pathmax.h posixtm.h quote.h quotearg.h readtokens.h \
path-concat.h pathmax.h physmem.h posixtm.h \
quote.h quotearg.h readtokens.h \
readutmp.h regex.h safe-read.h same.h save-cwd.h savedir.h sha.h \
strverscmp.h unicodeio.h version-etc.h xalloc.h xstrtod.h xstrtol.h

View File

@@ -129,7 +129,7 @@ libfetish_a_SOURCES = \
full-write.c getopt.c getopt1.c getstr.c getugroups.c hard-locale.c hash.c \
human.c idcache.c isdir.c linebuffer.c localcharset.c long-options.c \
makepath.c mbswidth.c md5.c memcasecmp.c memcoll.c modechange.c \
path-concat.c \
path-concat.c physmem.c \
quote.c quotearg.c readtokens.c safe-read.c same.c save-cwd.c \
savedir.c sha.c stripslash.c unicodeio.c userspec.c version-etc.c xgetcwd.c \
xgethostname.c xmalloc.c xstrdup.c xstrtod.c xstrtol.c xstrtoul.c \
@@ -146,7 +146,8 @@ noinst_HEADERS = \
getstr.h getpagesize.h group-member.h hard-locale.h hash.h human.h lchown.h \
linebuffer.h long-options.h mbswidth.h md5.h memcasecmp.h memcoll.h \
makepath.h mbswidth.h modechange.h mountlist.h nanosleep.h obstack.h \
path-concat.h pathmax.h posixtm.h quote.h quotearg.h readtokens.h \
path-concat.h pathmax.h physmem.h posixtm.h \
quote.h quotearg.h readtokens.h \
readutmp.h regex.h safe-read.h same.h save-cwd.h savedir.h sha.h \
strverscmp.h unicodeio.h version-etc.h xalloc.h xstrtod.h xstrtol.h
@@ -180,11 +181,12 @@ diacrit$U.o dirname$U.o exclude$U.o filemode$U.o full-write$U.o \
getopt$U.o getopt1$U.o getstr$U.o getugroups$U.o hard-locale$U.o \
hash$U.o human$U.o idcache$U.o isdir$U.o linebuffer$U.o \
localcharset$U.o long-options$U.o makepath$U.o mbswidth$U.o md5$U.o \
memcasecmp$U.o memcoll$U.o modechange$U.o path-concat$U.o quote$U.o \
quotearg$U.o readtokens$U.o safe-read$U.o same$U.o save-cwd$U.o \
savedir$U.o sha$U.o stripslash$U.o unicodeio$U.o userspec$U.o \
version-etc$U.o xgetcwd$U.o xgethostname$U.o xmalloc$U.o xstrdup$U.o \
xstrtod$U.o xstrtol$U.o xstrtoul$U.o xstrtoumax$U.o yesno$U.o
memcasecmp$U.o memcoll$U.o modechange$U.o path-concat$U.o physmem$U.o \
quote$U.o quotearg$U.o readtokens$U.o safe-read$U.o same$U.o \
save-cwd$U.o savedir$U.o sha$U.o stripslash$U.o unicodeio$U.o \
userspec$U.o version-etc$U.o xgetcwd$U.o xgethostname$U.o xmalloc$U.o \
xstrdup$U.o xstrtod$U.o xstrtol$U.o xstrtoul$U.o xstrtoumax$U.o \
yesno$U.o
libfetish_a_OBJECTS = $(am_libfetish_a_OBJECTS)
AR = ar
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -217,14 +219,15 @@ $(DEPDIR)/memchr.Po $(DEPDIR)/memcmp.Po $(DEPDIR)/memcoll$U.Po \
$(DEPDIR)/memcpy.Po $(DEPDIR)/memmove.Po $(DEPDIR)/memrchr.Po \
$(DEPDIR)/memset.Po $(DEPDIR)/mktime.Po $(DEPDIR)/modechange$U.Po \
$(DEPDIR)/mountlist.Po $(DEPDIR)/nanosleep.Po $(DEPDIR)/obstack.Po \
$(DEPDIR)/path-concat$U.Po $(DEPDIR)/posixtm$U.Po $(DEPDIR)/putenv.Po \
$(DEPDIR)/quote$U.Po $(DEPDIR)/quotearg$U.Po $(DEPDIR)/readtokens$U.Po \
$(DEPDIR)/readutmp.Po $(DEPDIR)/realloc.Po $(DEPDIR)/regex.Po \
$(DEPDIR)/rmdir.Po $(DEPDIR)/rpmatch.Po $(DEPDIR)/safe-read$U.Po \
$(DEPDIR)/same$U.Po $(DEPDIR)/save-cwd$U.Po $(DEPDIR)/savedir$U.Po \
$(DEPDIR)/sha$U.Po $(DEPDIR)/stat.Po $(DEPDIR)/stime.Po \
$(DEPDIR)/stpcpy.Po $(DEPDIR)/strcasecmp.Po $(DEPDIR)/strcspn.Po \
$(DEPDIR)/strdup.Po $(DEPDIR)/strftime.Po $(DEPDIR)/stripslash$U.Po \
$(DEPDIR)/path-concat$U.Po $(DEPDIR)/physmem$U.Po \
$(DEPDIR)/posixtm$U.Po $(DEPDIR)/putenv.Po $(DEPDIR)/quote$U.Po \
$(DEPDIR)/quotearg$U.Po $(DEPDIR)/readtokens$U.Po $(DEPDIR)/readutmp.Po \
$(DEPDIR)/realloc.Po $(DEPDIR)/regex.Po $(DEPDIR)/rmdir.Po \
$(DEPDIR)/rpmatch.Po $(DEPDIR)/safe-read$U.Po $(DEPDIR)/same$U.Po \
$(DEPDIR)/save-cwd$U.Po $(DEPDIR)/savedir$U.Po $(DEPDIR)/sha$U.Po \
$(DEPDIR)/stat.Po $(DEPDIR)/stime.Po $(DEPDIR)/stpcpy.Po \
$(DEPDIR)/strcasecmp.Po $(DEPDIR)/strcspn.Po $(DEPDIR)/strdup.Po \
$(DEPDIR)/strftime.Po $(DEPDIR)/stripslash$U.Po \
$(DEPDIR)/strncasecmp.Po $(DEPDIR)/strndup.Po $(DEPDIR)/strnlen.Po \
$(DEPDIR)/strpbrk.Po $(DEPDIR)/strstr.Po $(DEPDIR)/strtod.Po \
$(DEPDIR)/strtol.Po $(DEPDIR)/strtoul.Po $(DEPDIR)/strtoull.Po \
@@ -387,6 +390,8 @@ localcharset_.c: localcharset.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/localcharset.c; then echo $(srcdir)/localcharset.c; else echo localcharset.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > localcharset_.c
long-options_.c: long-options.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/long-options.c; then echo $(srcdir)/long-options.c; else echo long-options.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > long-options_.c
lstat_.c: lstat.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/lstat.c; then echo $(srcdir)/lstat.c; else echo lstat.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > lstat_.c
makepath_.c: makepath.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/makepath.c; then echo $(srcdir)/makepath.c; else echo makepath.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > makepath_.c
malloc_.c: malloc.c $(ANSI2KNR)
@@ -423,6 +428,8 @@ obstack_.c: obstack.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/obstack.c; then echo $(srcdir)/obstack.c; else echo obstack.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > obstack_.c
path-concat_.c: path-concat.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/path-concat.c; then echo $(srcdir)/path-concat.c; else echo path-concat.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > path-concat_.c
physmem_.c: physmem.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/physmem.c; then echo $(srcdir)/physmem.c; else echo physmem.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > physmem_.c
posixtm_.c: posixtm.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/posixtm.c; then echo $(srcdir)/posixtm.c; else echo posixtm.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > posixtm_.c
putenv_.c: putenv.c $(ANSI2KNR)
@@ -453,6 +460,8 @@ savedir_.c: savedir.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/savedir.c; then echo $(srcdir)/savedir.c; else echo savedir.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > savedir_.c
sha_.c: sha.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sha.c; then echo $(srcdir)/sha.c; else echo sha.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > sha_.c
stat_.c: stat.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/stat.c; then echo $(srcdir)/stat.c; else echo stat.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > stat_.c
stime_.c: stime.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/stime.c; then echo $(srcdir)/stime.c; else echo stime.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > stime_.c
stpcpy_.c: stpcpy.c $(ANSI2KNR)
@@ -522,19 +531,19 @@ fnmatch_.o fsusage_.o ftruncate_.o full-write_.o getdate_.o \
getgroups_.o gethostname_.o getline_.o getloadavg_.o getopt_.o \
getopt1_.o getpass_.o getstr_.o getugroups_.o getusershell_.o \
group-member_.o hard-locale_.o hash_.o human_.o idcache_.o isdir_.o \
lchown_.o linebuffer_.o localcharset_.o long-options_.o makepath_.o \
malloc_.o mbswidth_.o md5_.o memcasecmp_.o memchr_.o memcmp_.o \
memcoll_.o memcpy_.o memmove_.o memrchr_.o memset_.o mktime_.o \
modechange_.o mountlist_.o nanosleep_.o obstack_.o path-concat_.o \
posixtm_.o putenv_.o quote_.o quotearg_.o readtokens_.o readutmp_.o \
realloc_.o regex_.o rmdir_.o rpmatch_.o safe-read_.o same_.o \
save-cwd_.o savedir_.o sha_.o stime_.o stpcpy_.o strcasecmp_.o \
strcspn_.o strdup_.o strftime_.o stripslash_.o strncasecmp_.o \
strndup_.o strnlen_.o strpbrk_.o strstr_.o strtod_.o strtol_.o \
strtoul_.o strtoull_.o strtoumax_.o strverscmp_.o unicodeio_.o \
userspec_.o utime_.o version-etc_.o xgetcwd_.o xgethostname_.o \
xmalloc_.o xstrdup_.o xstrtod_.o xstrtol_.o xstrtoul_.o xstrtoumax_.o \
yesno_.o : $(ANSI2KNR)
lchown_.o linebuffer_.o localcharset_.o long-options_.o lstat_.o \
makepath_.o malloc_.o mbswidth_.o md5_.o memcasecmp_.o memchr_.o \
memcmp_.o memcoll_.o memcpy_.o memmove_.o memrchr_.o memset_.o \
mktime_.o modechange_.o mountlist_.o nanosleep_.o obstack_.o \
path-concat_.o physmem_.o posixtm_.o putenv_.o quote_.o quotearg_.o \
readtokens_.o readutmp_.o realloc_.o regex_.o rmdir_.o rpmatch_.o \
safe-read_.o same_.o save-cwd_.o savedir_.o sha_.o stat_.o stime_.o \
stpcpy_.o strcasecmp_.o strcspn_.o strdup_.o strftime_.o stripslash_.o \
strncasecmp_.o strndup_.o strnlen_.o strpbrk_.o strstr_.o strtod_.o \
strtol_.o strtoul_.o strtoull_.o strtoumax_.o strverscmp_.o \
unicodeio_.o userspec_.o utime_.o version-etc_.o xgetcwd_.o \
xgethostname_.o xmalloc_.o xstrdup_.o xstrtod_.o xstrtol_.o xstrtoul_.o \
xstrtoumax_.o yesno_.o : $(ANSI2KNR)
.y.c:
$(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c
if test -f y.tab.h; then \
@@ -637,6 +646,7 @@ maintainer-clean-tags:
@AMDEP@include $(DEPDIR)/nanosleep.Po
@AMDEP@include $(DEPDIR)/obstack.Po
@AMDEP@include $(DEPDIR)/path-concat$U.Po
@AMDEP@include $(DEPDIR)/physmem$U.Po
@AMDEP@include $(DEPDIR)/posixtm$U.Po
@AMDEP@include $(DEPDIR)/putenv.Po
@AMDEP@include $(DEPDIR)/quote$U.Po

View File

@@ -1,12 +1,17 @@
#ifndef PARAMS
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
# define PARAMS(Args) Args
# else
# define PARAMS(Args) ()
#ifndef CLOSEOUT_H
# define CLOSEOUT_H 1
# ifndef PARAMS
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
# define PARAMS(Args) Args
# else
# define PARAMS(Args) ()
# endif
# endif
#endif
void close_stdout_set_status PARAMS ((int status));
void close_stdout_set_file_name PARAMS ((const char *file));
void close_stdout PARAMS ((void));
void close_stdout_status PARAMS ((int status));
#endif

View File

@@ -34,6 +34,7 @@
# ASCII, ANSI_X3.4-1968 glibc solaris freebsd
# ISO-8859-1 glibc aix hpux irix osf solaris freebsd yes
# ISO-8859-2 glibc aix hpux irix solaris freebsd yes
# ISO-8859-3 glibc yes
# ISO-8859-4 solaris yes
# ISO-8859-5 glibc aix hpux irix solaris yes
# ISO-8859-6 glibc aix hpux solaris yes
@@ -41,28 +42,41 @@
# ISO-8859-8 glibc aix hpux solaris yes
# ISO-8859-9 glibc aix hpux irix osf solaris yes
# ISO-8859-13 glibc
# ISO-8859-15 aix solaris freebsd
# ISO-8859-15 glibc aix solaris freebsd
# KOI8-R glibc solaris freebsd yes
# KOI8-U glibc yes
# CP850 aix osf
# CP856 aix
# CP866 freebsd
# CP874 win32
# CP922 aix
# CP932 aix
# CP932 aix win32
# CP943 aix
# CP949 win32
# CP950 win32
# CP1046 aix
# CP1124 aix
# CP1129 aix
# CP1251 glibc
# CP1252 aix
# EUC-CN aix hpux irix solaris
# EUC-JP aix hpux irix solaris yes
# EUC-KR aix hpux irix solaris yes
# EUC-TW aix hpux irix solaris
# BIG5 aix hpux solaris yes
# GBK aix
# CP1250 win32
# CP1251 glibc win32
# CP1252 aix win32
# CP1253 win32
# CP1254 win32
# CP1255 win32
# CP1256 win32
# CP1257 win32
# GB2312 glibc aix hpux irix solaris yes
# EUC-JP glibc aix hpux irix solaris yes
# EUC-KR glibc aix hpux irix solaris yes
# EUC-TW glibc aix hpux irix solaris
# BIG5 glibc aix hpux solaris yes
# BIG5HKSCS glibc
# GBK aix win32
# GB18030 glibc
# SJIS hpux solaris
# TIS-620 aix hpux solaris
# JOHAB glibc win32
# TIS-620 glibc aix hpux solaris
# VISCII glibc yes
# HP-ROMAN8 hpux
# HP-ARABIC8 hpux
# HP-GREEK8 hpux
@@ -117,7 +131,7 @@ case "$os" in
echo "IBM-1124 CP1124"
echo "IBM-1129 CP1129"
echo "IBM-1252 CP1252"
echo "IBM-eucCN EUC-CN"
echo "IBM-eucCN GB2312"
echo "IBM-eucJP EUC-JP"
echo "IBM-eucKR EUC-KR"
echo "IBM-eucTW EUC-TW"
@@ -146,7 +160,7 @@ case "$os" in
echo "eucJP EUC-JP"
echo "eucKR EUC-KR"
echo "eucTW EUC-TW"
echo "hp15CN EUC-CN"
echo "hp15CN GB2312"
#echo "ccdc ?" # what is this?
echo "SJIS SJIS"
echo "utf8 UTF-8"
@@ -157,7 +171,7 @@ case "$os" in
echo "ISO8859-5 ISO-8859-5"
echo "ISO8859-7 ISO-8859-7"
echo "ISO8859-9 ISO-8859-9"
echo "eucCN EUC-CN"
echo "eucCN GB2312"
echo "eucJP EUC-JP"
echo "eucKR EUC-KR"
echo "eucTW EUC-TW"
@@ -181,7 +195,7 @@ case "$os" in
echo "ISO8859-15 ISO-8859-15"
echo "koi8-r KOI8-R"
echo "BIG5 BIG5"
echo "gb2312 EUC-CN"
echo "gb2312 GB2312"
echo "cns11643 EUC-TW"
echo "5601 EUC-KR"
echo "eucJP EUC-JP"
@@ -213,4 +227,8 @@ case "$os" in
echo "$l.CP866 CP866"
done
;;
beos*)
# BeOS has a single locale, and it has UTF-8 encoding.
echo "C UTF-8"
;;
esac

View File

@@ -43,26 +43,32 @@ void *memrchr ();
#include "dirname.h"
#ifndef FILESYSTEM_PREFIX_LEN
# define FILESYSTEM_PREFIX_LEN(Filename) 0
#endif
#ifndef ISSLASH
# define ISSLASH(C) ((C) == '/')
#endif
#define BACKSLASH_IS_PATH_SEPARATOR ISSLASH ('\\')
/* Return the length of `dirname (PATH)' and set *RESULT
to point to PATH or to `"."', as appropriate.
Works properly even if there are trailing slashes
(by effectively ignoring them). */
size_t
dir_name_r (const char *path, const char **result)
/* Return the length of `dirname (PATH)' and set *RESULT to point
to PATH or to `"."', as appropriate. Works properly even if
there are trailing slashes (by effectively ignoring them).
WARNING: This function doesn't work for cwd-relative names like
`a:foo' that are specified with a drive-letter prefix. That case
is handled in the caller. */
static size_t
dir_name_r (char const *path, char const **result)
{
char *slash;
int length; /* Length of result, not including NUL. */
char const *slash;
size_t length; /* Length of result, not including NUL. */
slash = strrchr (path, '/');
if (BACKSLASH_IS_PATH_SEPARATOR)
{
char *b = strrchr (path, '\\');
char const *b = strrchr (path, '\\');
if (b && slash < b)
slash = b;
}
@@ -78,10 +84,11 @@ dir_name_r (const char *path, const char **result)
if (path < slash)
{
slash = memrchr (path, '/', slash - path);
size_t len = slash - path;
slash = memrchr (path, '/', len);
if (BACKSLASH_IS_PATH_SEPARATOR)
{
char *b = memrchr (path, '\\', slash - path);
char const *b = memrchr (path, '\\', len);
if (b && slash < b)
slash = b;
}
@@ -91,27 +98,23 @@ dir_name_r (const char *path, const char **result)
if (slash == 0)
{
/* File is in the current directory. */
path = ".";
length = 1;
length = FILESYSTEM_PREFIX_LEN (path);
if (length == 0)
{
path = ".";
length = 1;
}
}
else
{
/* Remove any trailing slashes from the result. */
if (BACKSLASH_IS_PATH_SEPARATOR)
{
const char *lim = ((path[0] >= 'A' && path[0] <= 'z'
&& path[1] == ':')
? path + 2 : path);
/* Remove any trailing slashes from the result. If we have a
canonicalized "d:/path", leave alone the root case "d:/". */
char const *lim = path + FILESYSTEM_PREFIX_LEN (path);
/* If canonicalized "d:/path", leave alone the root case "d:/". */
while (slash > lim && ISSLASH (*slash))
--slash;
}
else
{
while (slash > path && ISSLASH (*slash))
--slash;
}
while (lim < slash && ISSLASH (*slash))
--slash;
length = slash - path + 1;
}
@@ -126,14 +129,18 @@ dir_name_r (const char *path, const char **result)
(by effectively ignoring them). */
char *
dir_name (const char *path)
dir_name (char const *path)
{
const char *result;
char const *result;
size_t length = dir_name_r (path, &result);
char *newpath = (char *) malloc (length + 1);
int append_dot = (length && length == FILESYSTEM_PREFIX_LEN (newpath));
char *newpath = (char *) malloc (length + append_dot + 1);
if (newpath == 0)
return 0;
strncpy (newpath, result, length);
/* If PATH is "d:foo", return "d:.", the CWD on drive d: */
if (append_dot)
newpath[length++] = '.';
newpath[length] = 0;
return newpath;
}
@@ -170,7 +177,7 @@ main ()
{
char path[MAX_BUFF_LEN];
char expected_result[MAX_BUFF_LEN];
char *result;
char const *result;
sscanf (buff, "%s %s", path, expected_result);
result = dir_name (path);
if (strcmp (result, expected_result))

View File

@@ -28,7 +28,4 @@
char *
dir_name PARAMS ((const char *path));
size_t
dir_name_r PARAMS ((const char *path, const char **result));
#endif /* not DIRNAME_H_ */

View File

@@ -22,11 +22,19 @@
#endif
#ifndef SHELLS_FILE
# ifndef __DJGPP__
/* File containing a list of nonrestricted shells, one per line. */
# define SHELLS_FILE "/etc/shells"
# define SHELLS_FILE "/etc/shells"
# else
/* This is a horrible kludge. Isn't there a better way? */
# define SHELLS_FILE "/dev/env/DJDIR/etc/shells"
# endif
#endif
#include <stdio.h>
#if HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include <ctype.h>
#include "xalloc.h"
@@ -40,9 +48,17 @@
static int readname ();
#if ! defined ADDITIONAL_DEFAULT_SHELLS && defined __MSDOS__
# define ADDITIONAL_DEFAULT_SHELLS \
"c:/dos/command.com", "c:/windows/command.com", "c:/command.com",
#else
# define ADDITIONAL_DEFAULT_SHELLS /* empty */
#endif
/* List of shells to use if the shells file is missing. */
static char const* const default_shells[] =
{
ADDITIONAL_DEFAULT_SHELLS
"/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", NULL
};

View File

@@ -37,12 +37,22 @@
# include <stdlib.h>
#endif
#if HAVE_LANGINFO_CODESET
# include <langinfo.h>
#else
# if HAVE_SETLOCALE
# include <locale.h>
#if defined _WIN32 || defined __WIN32__
# undef WIN32 /* avoid warning on mingw32 */
# define WIN32
#endif
#ifndef WIN32
# if HAVE_LANGINFO_CODESET
# include <langinfo.h>
# else
# if HAVE_SETLOCALE
# include <locale.h>
# endif
# endif
#else /* WIN32 */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
#ifndef DIRECTORY_SEPARATOR
@@ -73,6 +83,7 @@ get_charset_aliases ()
cp = charset_aliases;
if (cp == NULL)
{
#ifndef WIN32
FILE *fp;
const char *dir = LIBDIR;
const char *base = "charset.alias";
@@ -157,9 +168,20 @@ get_charset_aliases ()
}
}
charset_aliases = cp;
if (file_name != NULL)
free (file_name);
#else /* WIN32 */
/* To avoid the troubles of installing a separate file in the same
directory as the DLL and of retrieving the DLL's directory at
runtime, simply inline the aliases here. */
cp = "CP936" "\0" "GBK" "\0"
"CP1361" "\0" "JOHAB" "\0";
#endif
charset_aliases = cp;
}
return cp;
@@ -180,19 +202,21 @@ locale_charset ()
const char *codeset;
const char *aliases;
#if HAVE_LANGINFO_CODESET
#ifndef WIN32
# if HAVE_LANGINFO_CODESET
/* Most systems support nl_langinfo (CODESET) nowadays. */
codeset = nl_langinfo (CODESET);
#else
# else
/* On old systems which lack it, use setlocale and getenv. */
const char *locale = NULL;
# if HAVE_SETLOCALE
# if HAVE_SETLOCALE
locale = setlocale (LC_CTYPE, NULL);
# endif
# endif
if (locale == NULL || locale[0] == '\0')
{
locale = getenv ("LC_ALL");
@@ -209,6 +233,16 @@ locale_charset ()
through the charset.alias file. */
codeset = locale;
# endif
#else /* WIN32 */
static char buf[2 + 10 + 1];
/* Win32 has a function returning the locale's codepage as a number. */
sprintf (buf, "CP%u", GetACP ());
codeset = buf;
#endif
if (codeset != NULL && codeset[0] != '\0')

View File

@@ -153,7 +153,11 @@ mbsnwidth (const char *string, size_t nbytes, int flags)
/* An invalid multibyte sequence was encountered. */
{
if (flags & MBSW_ACCEPT_INVALID)
break;
{
p++;
width++;
break;
}
else
return -1;
}
@@ -162,7 +166,11 @@ mbsnwidth (const char *string, size_t nbytes, int flags)
/* An incomplete multibyte character at the end. */
{
if (flags & MBSW_ACCEPT_INVALID)
break;
{
p = plimit;
width++;
break;
}
else
return -1;
}

View File

@@ -145,7 +145,7 @@ extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
/* The following is from gnupg-1.0.2's cipher/bithelp.h. */
/* Rotate a 32 bit integer by n bytes */
#if defined(__GNUC__) && defined(__i386__)
#if defined __GNUC__ && defined __i386__
static inline md5_uint32
rol(md5_uint32 x, int n)
{

View File

@@ -21,12 +21,12 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdlib.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#undef __ptr_t
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
# define __ptr_t void *

View File

@@ -26,12 +26,31 @@
#endif
#include <stdio.h>
#if HAVE_STRING_H
# include <string.h>
#endif
#include <sys/types.h>
#if HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
# include <memory.h>
# endif
# include <string.h>
#else
# if HAVE_STRINGS_H
# include <strings.h>
# endif
#endif
#if HAVE_STDLIB_H
# include <stdlib.h>
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifndef HAVE_DECL_MALLOC
"this configure-time declaration test was not run"
#endif
#if !HAVE_DECL_MALLOC
char *malloc ();
#endif
#ifndef strdup
char *strdup ();
#endif

58
lib/physmem.c Normal file
View File

@@ -0,0 +1,58 @@
/* Calculate the size of physical memory.
Copyright 2000 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 Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Written by Paul Eggert. */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include "physmem.h"
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
/* Return the total amount of physical memory. */
double
physmem_total (void)
{
#if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE
double pages = sysconf (_SC_PHYS_PAGES);
double pagesize = sysconf (_SC_PAGESIZE);
if (0 <= pages && 0 <= pagesize)
return pages * pagesize;
#endif
/* Guess 64 MB. It's probably an older host, so guess small. */
return 64 * 1024 * 1024;
}
/* Return the amount of physical memory available. */
double
physmem_available (void)
{
#if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE
double pages = sysconf (_SC_AVPHYS_PAGES);
double pagesize = sysconf (_SC_PAGESIZE);
if (0 <= pages && 0 <= pagesize)
return pages * pagesize;
#endif
/* Guess 25% of physical memory. */
return physmem_total () / 4;
}

19
lib/physmem.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef PHYSMEM_H_
# define PHYSMEM_H_ 1
# if HAVE_CONFIG_H
# include <config.h>
# endif
# ifndef PARAMS
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
# define PARAMS(Args) Args
# else
# define PARAMS(Args) ()
# endif
# endif
double physmem_total PARAMS ((void));
double physmem_available PARAMS ((void));
#endif /* PHYSMEM_H_ */

View File

@@ -19,12 +19,16 @@
# include <config.h>
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#if STDC_HEADERS || HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif
#ifndef ISSLASH
# define ISSLASH(C) ((C) == '/')
#endif
/* Remove trailing slashes from PATH.
This is useful when using filename completion from a shell that
adds a "/" after directory names (such as tcsh and bash), because
@@ -37,6 +41,6 @@ strip_trailing_slashes (char *path)
int last;
last = strlen (path) - 1;
while (last > 0 && path[last] == '/')
while (0 < last && ISSLASH (path[last]))
path[last--] = '\0';
}

View File

@@ -163,8 +163,8 @@ is_number (const char *str)
use the given user's login group.
If SPEC_ARG contains a `:', then use that as the separator, ignoring
any `.'s. If there is no `:', but there is a `.', then first look
up SPEC_ARG as a login name. If that look-up fails, then try again
interpreting the `.' as a separator.
up the entire SPEC_ARG as a login name. If that look-up fails, then
try again interpreting the `.' as a separator.
USERNAME and GROUPNAME will be in newly malloc'd memory.
Either one might be NULL instead, indicating that it was not
@@ -304,7 +304,7 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
else
{
unsigned long int tmp_long;
if (xstrtoul (u, NULL, 0, &tmp_long, NULL) != LONGINT_OK
if (xstrtoul (g, NULL, 0, &tmp_long, NULL) != LONGINT_OK
|| tmp_long > MAXGID)
return _(E_invalid_group);
*gid = tmp_long;

View File

@@ -199,6 +199,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
break;
case 'G': /* Giga */
case 'g': /* 'g' is undocumented; for compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 3);
break;
@@ -207,7 +208,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
break;
case 'M': /* Mega */
case 'm': /* 'm' is undocumented; for backward compatibility only */
case 'm': /* 'm' is undocumented; for compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 2);
break;
@@ -216,6 +217,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
break;
case 'T': /* Tera */
case 't': /* 't' is undocumented; for compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 4);
break;

View File

@@ -1,3 +1,35 @@
2000-12-17 Jim Meyering <meyering@lucent.com>
* dos.m4 (jm_AC_DOS): New file and macro.
* jm-macros.m4 (jm_MACROS): Require jm_AC_DOS.
2000-12-06 Paul Eggert <eggert@twinsun.com>
* off_t-format.m4: Remove this file.
* jm-macros.m4 (jm_MACROS): Remove jm_SYS_OFF_T_PRINTF_FORMAT.
2000-12-06 Jim Meyering <meyering@lucent.com>
* xstrtoumax.m4 (jm_AC_PREREQ_XSTRTOUMAX): If we need the replacement
strtoull, we may well need the replacement strtoul, too.
Check for declarations of strtoul and strtoull.
Check for strtol. Mainly as a cue to cause automake to include
strtol.c -- that file is included by each of strtoul.c and strtoull.c.
Check for limits.h -- strtol.c needs it.
2000-12-02 Jim Meyering <meyering@lucent.com>
* off_t-format.m4 (OFF_T_PRINTF_FORMAT_STRING): New file/macro.
* jm-macros.m4 (jm_MACROS): require it.
2000-11-30 Jim Meyering <meyering@lucent.com>
* jm-macros.m4 (jm_MACROS): Check for stdint.h.
2000-11-30 Jim Meyering <meyering@lucent.com>
* getloadavg.m4: s/ifval/m4_ifval/ to accommodate new autoconf.
2000-11-03 Bruno Haible <haible@clisp.cons.org>
* jm-macros.m4 (jm_MACROS): Add test for wcrtomb.

View File

@@ -11,6 +11,7 @@ chown.m4 \
codeset.m4 \
d-ino.m4 \
d-type.m4 \
dos.m4 \
error.m4 \
fnmatch.m4 \
fpending.m4 \

View File

@@ -126,6 +126,7 @@ chown.m4 \
codeset.m4 \
d-ino.m4 \
d-type.m4 \
dos.m4 \
error.m4 \
fnmatch.m4 \
fpending.m4 \

27
m4/dos.m4 Normal file
View File

@@ -0,0 +1,27 @@
# serial 1
# Define some macros required for proper operation of code in lib/*.c
# on MSDOS/Windows systems.
# From Jim Meyering.
AC_DEFUN(jm_AC_DOS,
[
# FIXME: this is incomplete. Add a compile-test that does something
# like this:
#if defined _WIN32 || defined __WIN32__ || defined __MSDOS__
ac_fspl_def="((Filename)[0] && (Filename)[1] == ':' ? 2 : 0)"
ac_fspl_def=0
AC_DEFINE_UNQUOTED([FILESYSTEM_PREFIX_LEN(Filename)], $ac_fspl_def,
[On systems for which file names may have a so-called `drive letter'
prefix, define this to compute the length of that prefix, including
the colon. Otherwise, define it to zero.])
ac_isslash_def="((C) == '/' || (C) == '\\')"
ac_isslash_def="((C) == '/')"
AC_DEFINE_UNQUOTED([ISSLASH(C)], $ac_isslash_def,
[Define to return nonzero for any character that may serve as
a file name component separator. On POSIX systems, it is the
slash character. Some other systems also accept backslash.])
])

View File

@@ -1,4 +1,4 @@
#serial 7
#serial 8
# A replacement for autoconf's macro by the same name. This version
# accepts an optional argument specifying the name of the $srcdir-relative
@@ -15,7 +15,7 @@ AC_DEFUN([AC_FUNC_GETLOADAVG],
# By default, expect to find getloadavg.c in $srcdir/.
ac_lib_dir_getloadavg=$srcdir
# But if there's an argument, DIR, expect to find getloadavg.c in $srcdir/DIR.
ifval([$1], [ac_lib_dir_getloadavg=$srcdir/$1])
m4_ifval([$1], [ac_lib_dir_getloadavg=$srcdir/$1])
# Make sure getloadavg.c is where it belongs, at ./configure-time.
test -f $ac_lib_dir_getloadavg/getloadavg.c \
|| AC_MSG_ERROR([getloadavg.c is not in $ac_lib_dir_getloadavg])

View File

@@ -1,4 +1,4 @@
#serial 27
#serial 29 -*- autoconf -*-
dnl Misc type-related macros for fileutils, sh-utils, textutils.
@@ -32,6 +32,7 @@ AC_DEFUN(jm_MACROS,
paths.h \
stdlib.h \
stddef.h \
stdint.h \
string.h \
sys/acl.h \
sys/filsys.h \
@@ -222,6 +223,7 @@ AC_DEFUN(jm_MACROS,
AC_LIBOBJ(fsusage)
AC_LIBOBJ(mountlist)
fi
AC_REQUIRE([jm_AC_DOS])
])

View File

@@ -1,4 +1,4 @@
#serial 2
#serial 3
# autoconf tests required for use of xstrtoumax.c
@@ -7,7 +7,8 @@ AC_DEFUN(jm_AC_PREREQ_XSTRTOUMAX,
AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])
AC_REQUIRE([jm_AC_HEADER_INTTYPES_H])
AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG])
AC_CHECK_HEADERS(stdlib.h)
AC_CHECK_DECLS([strtoul, strtoull])
AC_CHECK_HEADERS(limits.h stdlib.h)
AC_CACHE_CHECK([whether <inttypes.h> defines strtoumax as a macro],
jm_cv_func_strtoumax_macro,
@@ -28,7 +29,13 @@ AC_DEFUN(jm_AC_PREREQ_XSTRTOUMAX,
dnl so we need the replacement strtoull only if strtoumax does not exist.
case "$ac_cv_type_unsigned_long_long,$jm_cv_func_strtoumax_macro,$ac_cv_func_strtoumax" in
yes,no,no)
AC_REPLACE_FUNCS(strtoull)
AC_REPLACE_FUNCS(strtoull strtol)
;;
esac
case "$jm_cv_func_strtoumax_macro,$ac_cv_func_strtoumax" in
no,no)
AC_REPLACE_FUNCS(strtoul strtol)
;;
esac

View File

@@ -1,8 +1,182 @@
2000-12-22 Jim Meyering <meyering@lucent.com>
* Version 4.0.34.
* src/shred.c (isaac_seed_machdep) [_ARCH_PPC]: Disable the code
that would use the PPC mfspr `asm' code. Suggestion from Michael Stone.
2000-12-19 Jim Meyering <meyering@lucent.com>
* doc/fileutils.texi: Use `ref_file' in place of `file' to make
descriptions of the various --reference=... options clearer.
2000-12-17 Jim Meyering <meyering@lucent.com>
* doc/texinfo.tex: Update from master repository.
* config.sub: Likewise.
* config.guess: Likewise.
2000-12-16 Jim Meyering <meyering@lucent.com>
* src/chown-core.c (uint_to_string): New function.
(uid_to_name): Use it.
(gid_to_name): Use it.
Rename locals, user/group, to uid/gid.
* src/chown-core.h (enum Change_status): Start with 1.
* src/chown.c (main): Rename locals, user/group, to uid/gid.
* src/chgrp.c (main): Rename local, group, to gid.
* tests/group-names: New file.
* tests/Makefile.am (EXTRA_DIST): Add group-names.
* tests/chgrp/basic: Use group-names.
* tests/chgrp/deref: Likewise.
* tests/chgrp/recurse: Likewise.
* tests/chgrp/basic: Don't assume that creating a file gives it
group $g1.
* tests/chgrp/Makefile.am (TESTS): Add recurse.
2000-12-15 Jim Meyering <meyering@lucent.com>
* src/chown-core.h [enum Dereference_symlink] (dereference): Rename
from change_symlinks.
* src/chown-core.c: Declare lstat.
Rename change_symlinks member to `dereference' and use the DEREF_*
enum values.
(describe_change): Merge the chgrp and chown switch statements.
Use xmalloc to form the `user:group' string.
(change_file_owner): Record (and later, use) is_symlink and is_directory
from the lstat stats, in order to control whether we operate on symlinks
and whether (with -R) we traverse symlinks to directories.
When dereferencing, use open/fchown (rather than chown) on symlinks.
* src/chown.c (main): Reflect renaming: s/dereference/change_symlinks/.
* src/chgrp.c (main): Likewise.
* src/chown-core.c (describe_change): Use `:' (not `.') to separate the
username and group in messages evoked by the --verbose and --changes
options.
2000-12-09 Jim Meyering <meyering@lucent.com>
* src/Makefile.am (noinst_HEADERS): Add chown-core.h.
(chown_SOURCES): Define.
(chgrp_SOURCES): Define.
* src/chgrp.c: Include "chown-core.h".
[enum Change_status, enum Verbosity]: Remove declarations.
Remove decls of globals that are now part of struct Chown_option.
Remove decl of xstat.
(describe_change): Remove function.
(change_file_group): Likewise.
(change_dir_group): Likewise.
(parse_group): Don't set global, groupname, here...
(main): ... instead, initialize `chopt.group_name' here.
Initialize chopt and update uses of the now-members.
Set group_name also when it's obtained via a --reference=FILE option.
Call change_file_owner (with -1 for uids), not change_file_group.
* src/chown.c: Don't include pwd.h or grp.h -- no longer needed.
Include "chown-core.h".
[enum Change_status, enum Verbosity]: Remove declarations.
Remove decls of globals that are now part of struct Chown_option.
(describe_change): Remove function.
(change_file_owner): Likewise.
(change_dir_owner): Likewise.
(main): Initialize chopt and update uses of the now-members.
Set user_name and group_name also when they're obtained via a
--reference=FILE option.
Pass `chopt' to change_file_owner.
* src/chown-core.c: Include <pwd.h>, <grp.h>, and "xalloc.h".
[!_POSIX_VERSION]: Declare getgrnam and getgrgid.
(gid_to_name): New function.
(uid_to_name): Likewise.
(chopt_free): Likewise.
Factor out code that's common to chgrp.c and chown.c.
* src/chown-core.h: New file.
* src/chown-core.c (chopt_init): New function.
(describe_change): Extracted/combined from chgrp.c and chown.c.
(change_dir_owner): Likewise.
(change_file_owner): Likewise.
* po/POTFILES.in: Add src/chown-core.c.
* configure.in (AC_OUTPUT): Add tests/chgrp/Makefile.
* tests/Makefile.am (SUBDIRS): Add chgrp.
* tests/chgrp: New directory.
* tests/chgrp/basic: New test.
* tests/chgrp/deref: Likewise.
* tests/chgrp/Makefile.am: New file.
* src/chown.c (change_file_owner): Restore special file permission
bits, since calling chown resets them on some systems.
Reported by Matt Perry.
2000-12-08 Andreas Schwab <schwab@suse.de>
* tests/mv/mv-special-1: Don't make the success of the test depend
on the order in which directory entries are processed.
2000-12-03 Jim Meyering <meyering@lucent.com>
* src/ls.c (gobble_file) [USE_ACL]: Set have_acl member unconditionally
to avoid uninitialized memory reference via FILE_HAS_ACL.
* Makefile.maint (alpha): Use rsync rather than scp, so the destination
file is created only after the successful completion of the copy.
2000-12-02 Jim Meyering <meyering@lucent.com>
* tests/ls/Makefile.am (TESTS): Add follow-slink.
* tests/ls/follow-slink: New file.
2000-12-01 Paul Eggert <eggert@twinsun.com>
* src/ls.c (gobble_file): Do not fall back on lstat if stat
fails; POSIX.2 does not allow this. Invoke acl only on
non-symlinks, and only if lstat or stat succeeds.
2000-12-02 Jim Meyering <meyering@lucent.com>
* configure: Regenerate using the very latest version (in CVS) of
autoconf.
* tests/dd/skip-seek: Remove test #2, now that support for the
`B' suffix is gone.
* tests/dd/Makefile.am (TESTS): Add skip-seek2
* tests/dd/skip-seek2: New file.
2000-12-01 Paul Eggert <eggert@twinsun.com>
* src/dd.c (skip, dd_copy): Use ssize_t to store result of
safe_read, to avoid overflow e.g. on 64-bit Solaris sparc.
(dd_copy): Remove unnecessary cast.
2000-12-01 Paul Eggert <eggert@twinsun.com>
* doc/fileutils.texi: Remove B suffix. Document how to have
the desired effect without it.
* src/dd.c: Undo most of the changes since 2000-11-24, since we've
documented a standard way to do it.
(skip_bytes, seek_bytes): Remove.
(usage): Remove B suffix.
(scanargs, skip, dd_copy, main): Remove support for B suffix.
2000-11-28 Jim Meyering <meyering@lucent.com>
* src/mkdir.c (main): Remove any trailing slash unconditionally.
Reported by Volker Borchert.
* tests/mkdir/t-slash: Add a test for this.
2000-11-27 Jim Meyering <meyering@lucent.com>
* Version 4.0.33.
* tests/touch/no-rights: Use touch with `-d tomorrow' to avoid
* tests/touch/no-rights: Use touch with `-d tomorrow' to avoid a
race condition.
* tests/Fetish.pm (_compare_files): New function.

View File

@@ -1,7 +1,17 @@
Changes in release 4.01:
[4.0.34]
* fix a bug (introduced in 4.0z) that made `chown 123:456 file' act like
`chown 123:123 file'. Other uses with a numeric group ID would cause
chown to fail when it shouldn't have.
* the chown and chgrp programs preserve set-uid and set-gid bits, even on
systems for which the chown function call resets those bits.
* `ls -L dangling-symlink' now fails (per POSIX) rather than printing the
link name
* dd no longer honors the just-added `B' suffix on skip= and seek= arguments.
* `mkdir no-such-dir/' no longer fails on NetBSD systems
[4.0.33]
* dd now accepts skip=nB and seek=nB, to advance past some number of bytes, n,
that is smaller than the block size.
that need not be a multiple of the block size.
* dd (without conv=notrunc) now uses ftruncate only on regular files
* chmod --changes (-c) once again issues diagnostics only for the files
with changed permissions

View File

@@ -1,6 +1,33 @@
2000-12-17 Jim Meyering <meyering@lucent.com>
* doc/texinfo.tex: Update from master repository.
* config.sub: Likewise.
* config.guess: Likewise.
* djgpp: New directory.
* djgpp/*: New files.
* Makefile.am (SUBDIRS): Add djgpp.
* configure.in (AC_OUTPUT): Add djgpp/Makefile.
From Prashant TR.
2000-12-08 Jim Meyering <meyering@lucent.com>
* src/dirname.c: Include xalloc.h.
(main): Use dir_name rather than the underlying dir_name_r.
The former now handles cwd-relative names with drive-letter prefixes.
2000-12-02 Jim Meyering <meyering@lucent.com>
* src/seq.c (valid_format): Move pre-increment to a separate statement
to avoid a warning.
* src/id.c: Move dcls of globals used only in main...
(main): ...to here.
(usage): Clarify option descriptions.
2000-11-18 Jim Meyering <meyering@lucent.com>
* Version 2.0.12.
* po/Makefile.in.in: Sync with the one from fileutils.
* configure, config.h.in, Makefile.in, etc.: Regenerate using the
very latest version (in CVS) of autoconf.

View File

@@ -1,7 +1,193 @@
2000-11-27 Jim Meyering <meyering@lucent.com>
2000-12-19 Jim Meyering <meyering@lucent.com>
* Version 2.0.11.
2000-12-18 Paul Eggert <eggert@twinsun.com>
* NEWS, doc/textutils.texi: New "sort" option -S SIZE.
* src/sys2.h (UINTMAX_MAX): New macro, taken from C99.
* src/sort.c: Include physmem.h.
(SORTALLOC, mergealloc, LINEALLOC): Remove.
(sortalloc): Default to zero at program startup.
(SORTALLOC_MIN, SORTALLOC_DEFAULT_MIN): New macros.
(usage, main): Add support for new -S SIZE option.
(specify_sort_size, default_sort_size): New functions.
(initlines): Do not let alloc exceed limit.
(findlines): Likewise.
(checkfp, mergefps, sort): Use sortalloc to size everything
else, instead of relying on precomputed sizes.
2000-12-17 Jim Meyering <meyering@lucent.com>
* doc/texinfo.tex: Update from master repository.
* config.sub: Likewise.
* config.guess: Likewise.
2000-12-11 Jim Meyering <meyering@lucent.com>
* Version 2.0.10.
2000-12-07 Jim Meyering <meyering@lucent.com>
* src/od.c (address_base): Declare to be static.
2000-12-06 Paul Eggert <eggert@twinsun.com>
* src/od.c (address_base, address_pad_len): New var.
(output_address_fmt_string, address_fmt_buffer, address_pad): Remove.
(flag_pseudo_start): Now int, not long int.
(pseudo_offset): Now off_t, not long int.
(n_specs, n_specs_allocated): Now size_t, not unsigned int.
(format_address, format_address_none, format_address_std,
format_address_label): Now accepts an extra char argument (an extra
char to print if nonzero), and prints instead of returning a string.
All callers changed.
(bytes_per_block): Now size_t, not int.
(format_address_none): Do not even print the extra char argument.
This simplifies the callers.
(format_address_std, format_address_label): Print off_t ourself
instead of trying to use autoconfigured format. This is faster and
more portable.
(format_address_paren): New function.
(dump): Remove unnecessary cast.
(expand_address_fmt): Remove.
(main): Use size_t, off_t, etc. instead of builtin types where this is
advisable. Adjust to above changes. Remove unnecessary cast.
2000-12-03 Jim Meyering <meyering@lucent.com>
* src/tail.c (tail_file): Initialize ignore, dev, and ino members,
when tailing forever and the open failed. Otherwise, we could get
uninitialized memory references of those fields in recheck.
* tests/tail-2/Makefile.am (TESTS): Add assert-2.
* tests/tail-2/assert-2: New file.
* Version 2.0.9.
Make od print valid addresses for offsets of 2^32 and larger, and
allow byte offset (-j) and byte count (-N) to be 2^32 and larger.
* src/od.c (MAX_ADDRESS_LENGTH): Don't hard-code as a literal.
Rather, define in terms of the type, off_t.
(string_min): Declare to be of type size_t.
(flag_dump_strings): Declare to be of type int.
(print_s_char): Declare the n_bytes parameter and the local, `i',
to be of type off_t.
(print_char): Likewise.
(print_s_short): Likewise.
(print_short): Likewise.
(print_int): Likewise.
(print_long): Likewise.
(print_long_long): Likewise.
(print_float): Likewise.
(print_double): Likewise.
(print_long_double): Likewise.
(dump_hexl_mode_trailer): Likewise.
(print_named_ascii): Likewise.
(print_ascii): Likewise.
(write_block): Likewise.
(print_ascii): Declare local, `print_function' with a prototype.
Change a few `>' comparisons to the equivalent `<' form.
(parse_options): Declare `tmp' to be of type uintmax_t.
Use xstrtoumax, not xstrtoul.
Fail if the specified offset if larger than OFF_T_MAX.
(dump_strings): Declare local `i' to be of type size_t.
Remove the now-unnecessary cast-to-off_t.
(main) [IF_LINT]: Initialize desired_width to avoid a warning.
Declare `tmp' to be of type uintmax_t.
Use xstrtoumax, not xstrtoul.
Fail if minimum string length is larger than SIZE_MAX.
Fail if specified width is larger than ULONG_MAX.
* src/od.c (format_address): Use off_t, not long unsigned_int as the
parameter type.
(format_address_none): Likewise. Mark parameter as unused.
(format_address_std): Likewise.
(format_address_label): Likewise.
(print_ascii): Mark format string parameter as unused.
(write_block): Use off_t, not long unsigned_int as offset type.
(expand_address_fmt): New function.
(main): Use it to expand each address format string template.
Reported by Mark Nudelman, via Andreas Jaeger.
* src/sys2.h (OFF_T_MIN): Define here instead.
(OFF_T_MAX): Likewise.
(CHAR_BIT): Define.
* src/tail.c (parse_options): Use xstrtoumax to parse the byte and line
offset. Give a better diagnostic when the requested offset is still
representable but larger than OFF_T_MAX.
(OFF_T_MIN): Remove definition.
(OFF_T_MAX): Likewise.
2000-12-02 Jim Meyering <meyering@lucent.com>
* src/sort.c (checkfp): Rename local `buf' to avoid shadowing previous
declaration.
* src/sort.c (NONZERO): Define and use it to make the code a tiny
bit more readable.
* doc/textutils.texi (sort invocation): Clarify how -t works
when a sort key specifies a range of fields. From Karl O. Pinc.
2000-11-26 Paul Eggert <eggert@twinsun.com>
* src/od.c (skip): Use lseek instead of worrying about fseeko or fseek.
This should be portable, as we seek before doing any I/O.
(fseeko): Remove; no longer used.
2000-11-30 Jim Meyering <meyering@lucent.com>
* src/sort.c: s/SIZE_T_MAX/SIZE_MAX/.
2000-11-30 Paul Eggert <eggert@twinsun.com>
* src/sys2.h: Include <stdint.h> if HAVE_STDINT_H.
(SIZE_MAX): Renamed from SIZE_T_MAX, as C99 uses SIZE_MAX.
All uses changed.
2000-11-30 Jim Meyering <meyering@lucent.com>
* src/sort.c: SIZE_MAX is not defined, so s/SIZE_MAX/SIZE_T_MAX/, and...
* src/sys2.h (SIZE_T_MAX): ... define.
2000-11-29 Paul Eggert <eggert@twinsun.com>
Port GNU "sort" to hosts where sizes don't fit in "int",
e.g. 64-bit Solaris (sparc).
* src/sort.c ("human.h", "xstrtol.h"): Include.
(struct line): length member is now size_t, not int.
(struct lines): Likewise for used, alloc, limit members.
(struct buffer): Likewise for used, alloc, left, newline_free members.
(struct keyfield): Likewise for sword, schar, eword, echar members.
(sortalloc, mergealloc, linelength): Now size_t, not int.
(initbuf, fillbuf, initlines, begfield, limfield, findlines,
numcompare, getmonth, keycompare, compare, checkfp, mergefps,
sortlines, sort): Accept, return, and use size_t for sizes, not int.
(fillbuf, initlines, findlines, checkfp, sort): Check for overflow
when computing buffer sizes.
(begfield, limfield): Do not index past end of array.
(checkfp): Return a boolean, not a line number, as the line
number may not fit in int. All callers changed. Use
uintmax_t for line numbers, not int.
(sort): Don't allocate tmp until we need it (and know the right size).
(parse_field_count): New function.
(main): Use it to check for overflow in field counts.
"outfile" is now a pointer to const.
2000-11-27 Jim Meyering <meyering@lucent.com>
* src/checksum.h: Don't include system.h here.
* src/md5.c: Include config.h, stdio.h, sys/types.h. and system.h here
instead.

View File

@@ -1,5 +1,14 @@
Changes in release 2.1
[2.0.11]
* sort accepts new -S SIZE option, to specify main-memory usage.
[2.0.10]
* od is faster and more portable than it was in 2.0.9
* tail avoids an uninitialized memory reference
[2.0.9]
* od now prints valid addresses for offsets of 2^32 and larger, and allows
the byte offset (-j) and byte count (-N) arguments to be 2^32 and larger.
* tail now works with line and byte counts of 2^32 and larger, on systems
with large file support
* join now works with an 8-bit delimiter
* fix a compilation failure on some Solaris systems with wc.c
[2.0.8]

View File

@@ -30,6 +30,7 @@
#include "quote.h"
#include "savedir.h"
#include "xstrtol.h"
#include "chown-core.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "chgrp"
@@ -52,54 +53,9 @@ struct group *getgrnam ();
# define endgrent() ((void) 0)
#endif
enum Change_status
{
CH_NOT_APPLIED,
CH_SUCCEEDED,
CH_FAILED,
CH_NO_CHANGE_REQUESTED
};
enum Verbosity
{
/* Print a message for each file that is processed. */
V_high,
/* Print a message for each file whose attributes we change. */
V_changes_only,
/* Do not be verbose. This is the default. */
V_off
};
int lstat ();
static int change_dir_group PARAMS ((const char *dir, gid_t group,
const struct stat *statp));
/* The name the program was run with. */
char *program_name;
/* If nonzero, and the systems has support for it, change the ownership
of symbolic links rather than any files they point to. */
static int change_symlinks = 1;
/* When change_symlinks is set, this should be set to `lstat', otherwise,
it should be `stat'. */
static int (*xstat) ();
/* If nonzero, change the ownership of directories recursively. */
static int recurse;
/* If nonzero, force silence (no error messages). */
static int force_silent;
/* Level of verbosity. */
static enum Verbosity verbosity = V_off;
/* The name of the group to which ownership of the files is being given. */
static const char *groupname;
/* The argument to the --reference option. Use the group ID of this file.
This file must exist. */
static char *reference_file;
@@ -127,38 +83,6 @@ static struct option const long_options[] =
{0, 0, 0, 0}
};
/* Tell the user how/if the group of FILE has been changed.
CHANGED describes what (if anything) has happened. */
static void
describe_change (const char *file, enum Change_status changed)
{
const char *fmt;
if (changed == CH_NOT_APPLIED)
{
printf (_("neither symbolic link %s nor referent has been changed\n"),
quote (file));
return;
}
switch (changed)
{
case CH_SUCCEEDED:
fmt = _("group of %s changed to %s\n");
break;
case CH_FAILED:
fmt = _("failed to change group of %s to %s\n");
break;
case CH_NO_CHANGE_REQUESTED:
fmt = _("group of %s retained as %s\n");
break;
default:
abort ();
}
printf (fmt, quote (file), groupname);
}
/* Set *G according to NAME. */
static void
@@ -166,7 +90,6 @@ parse_group (const char *name, gid_t *g)
{
struct group *grp;
groupname = name;
if (*name == '\0')
error (1, 0, _("can not change to null group"));
@@ -193,139 +116,6 @@ parse_group (const char *name, gid_t *g)
endgrent (); /* Save a file descriptor. */
}
/* Change the ownership of FILE to GID GROUP.
If it is a directory and -R is given, recurse.
Return 0 if successful, 1 if errors occurred. */
static int
change_file_group (int cmdline_arg, const char *file, gid_t group)
{
struct stat file_stats;
int errors = 0;
if ((*xstat) (file, &file_stats))
{
if (force_silent == 0)
error (0, errno, _("getting attributes of %s"), quote (file));
return 1;
}
if (group != file_stats.st_gid)
{
int fail;
int symlink_changed = 1;
int saved_errno;
if (S_ISLNK (file_stats.st_mode) && change_symlinks)
{
fail = lchown (file, (uid_t) -1, group);
/* Ignore the failure if it's due to lack of support (ENOSYS)
and this is not a command line argument. */
if (!cmdline_arg && fail && errno == ENOSYS)
{
fail = 0;
symlink_changed = 0;
}
}
else
{
fail = chown (file, (uid_t) -1, group);
}
/* Save errno, since in verbose mode, describe_change might change it. */
saved_errno = errno;
if (verbosity == V_high || (verbosity == V_changes_only && !fail))
{
enum Change_status ch_status = (! symlink_changed ? CH_NOT_APPLIED
: (fail ? CH_FAILED : CH_SUCCEEDED));
describe_change (file, ch_status);
}
if (fail)
{
errors = 1;
if (force_silent == 0)
{
/* Give a more specific message. Some systems set errno
to EPERM for both `inaccessible file' and `user not a member
of the specified group' errors. */
if (saved_errno == EPERM && !group_member (group))
{
error (0, saved_errno, _("you are not a member of group %s"),
quote (groupname));
}
else if (saved_errno == EINVAL && group > MAXUID)
{
error (0, 0, _("%s: invalid group number"),
quote (groupname));
}
else
{
error (0, saved_errno, _("changing group of %s"),
quote (file));
}
}
}
}
else if (verbosity == V_high)
{
describe_change (file, CH_NO_CHANGE_REQUESTED);
}
if (recurse && S_ISDIR (file_stats.st_mode))
errors |= change_dir_group (file, group, &file_stats);
return errors;
}
/* Recursively change the ownership of the files in directory DIR
to GID GROUP.
STATP points to the results of lstat on DIR.
Return 0 if successful, 1 if errors occurred. */
static int
change_dir_group (const char *dir, gid_t group, const struct stat *statp)
{
char *name_space, *namep;
char *path; /* Full path of each entry to process. */
unsigned dirlength; /* Length of `dir' and '\0'. */
unsigned filelength; /* Length of each pathname to process. */
unsigned pathlength; /* Bytes allocated for `path'. */
int errors = 0;
name_space = savedir (dir, statp->st_size);
if (name_space == NULL)
{
if (force_silent == 0)
error (0, errno, "%s", quote (dir));
return 1;
}
dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
pathlength = dirlength + 1;
/* Give `path' a dummy value; it will be reallocated before first use. */
path = xmalloc (pathlength);
strcpy (path, dir);
path[dirlength - 1] = '/';
for (namep = name_space; *namep; namep += filelength - dirlength)
{
filelength = dirlength + strlen (namep) + 1;
if (filelength > pathlength)
{
pathlength = filelength * 2;
path = xrealloc (path, pathlength);
}
strcpy (path + dirlength, namep);
errors |= change_file_group (0, path, group);
}
free (path);
free (name_space);
return errors;
}
void
usage (int status)
{
@@ -364,9 +154,10 @@ Change the group membership of each FILE to GROUP.\n\
int
main (int argc, char **argv)
{
gid_t group;
gid_t gid;
int errors = 0;
int optc;
struct Chown_option chopt;
program_name = argv[0];
setlocale (LC_ALL, "");
@@ -375,7 +166,7 @@ main (int argc, char **argv)
atexit (close_stdout);
recurse = force_silent = 0;
chopt_init (&chopt);
while ((optc = getopt_long (argc, argv, "Rcfhv", long_options, NULL)) != -1)
{
@@ -387,22 +178,22 @@ main (int argc, char **argv)
reference_file = optarg;
break;
case DEREFERENCE_OPTION:
change_symlinks = 0;
chopt.dereference = DEREF_ALWAYS;
break;
case 'R':
recurse = 1;
chopt.recurse = 1;
break;
case 'c':
verbosity = V_changes_only;
chopt.verbosity = V_changes_only;
break;
case 'f':
force_silent = 1;
chopt.force_silent = 1;
break;
case 'h':
change_symlinks = 1;
chopt.dereference = DEREF_NEVER;
break;
case 'v':
verbosity = V_high;
chopt.verbosity = V_high;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -417,24 +208,26 @@ main (int argc, char **argv)
usage (1);
}
if (change_symlinks)
xstat = lstat;
else
xstat = stat;
if (reference_file)
{
struct stat ref_stats;
if (stat (reference_file, &ref_stats))
error (1, errno, _("getting attributes of %s"), quote (reference_file));
group = ref_stats.st_gid;
chopt.group_name = gid_to_name (ref_stats.st_gid);
gid = ref_stats.st_gid;
}
else
parse_group (argv[optind++], &group);
{
chopt.group_name = argv[optind++];
parse_group (chopt.group_name, &gid);
}
for (; optind < argc; ++optind)
errors |= change_file_group (1, argv[optind], group);
errors |= change_file_owner (1, argv[optind], (uid_t) -1, gid,
(uid_t) -1, (gid_t) -1, &chopt);
chopt_free (&chopt);
exit (errors);
}

366
src/chown-core.c Normal file
View File

@@ -0,0 +1,366 @@
/* chown-core.c -- core functions for changing ownership.
Copyright (C) 2000 Free Software Foundation.
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 Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Extracted from chown.c/chgrp.c and librarified by Jim Meyering. */
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include "system.h"
#include "error.h"
#include "lchown.h"
#include "quote.h"
#include "savedir.h"
#include "chown-core.h"
#include "xalloc.h"
/* The number of decimal digits required to represent the largest value of
type `unsigned int'. This is enough for an 8-byte unsigned int type. */
#define UINT_MAX_DECIMAL_DIGITS 20
#ifndef _POSIX_VERSION
struct group *getgrnam ();
struct group *getgrgid ();
#endif
int lstat ();
void
chopt_init (struct Chown_option *chopt)
{
chopt->verbosity = V_off;
chopt->dereference = DEREF_NEVER;
chopt->recurse = 0;
chopt->force_silent = 0;
chopt->user_name = 0;
chopt->group_name = 0;
}
void
chopt_free (struct Chown_option *chopt)
{
/* Deliberately do not free chopt->user_name or ->group_name.
They're not always allocated. */
}
/* Convert N to a string, and return a pointer to that string in memory
allocated from the heap. */
static char *
uint_to_string (unsigned int n)
{
char buf[UINT_MAX_DECIMAL_DIGITS + 1];
char *p = buf + sizeof buf;
*--p = '\0';
do
*--p = '0' + (n % 10);
while ((n /= 10) != 0);
return xstrdup (p);
}
/* Convert the numeric group-id, GID, to a string stored in xmalloc'd memory,
and return it. If there's no corresponding group name, use the decimal
representation of the ID. */
char *
gid_to_name (gid_t gid)
{
struct group *grp = getgrgid (gid);
return grp ? xstrdup (grp->gr_name) : uint_to_string (gid);
}
/* Convert the numeric user-id, UID, to a string stored in xmalloc'd memory,
and return it. If there's no corresponding user name, use the decimal
representation of the ID. */
char *
uid_to_name (uid_t uid)
{
struct passwd *pwd = getpwuid (uid);
return pwd ? xstrdup (pwd->pw_name) : uint_to_string (uid);
}
/* Tell the user how/if the user and group of FILE have been changed.
If USER is NULL, give the group-oriented messages.
CHANGED describes what (if anything) has happened. */
static void
describe_change (const char *file, enum Change_status changed,
char const *user, char const *group)
{
const char *fmt;
char *spec;
int spec_allocated = 0;
if (changed == CH_NOT_APPLIED)
{
printf (_("neither symbolic link %s nor referent has been changed\n"),
quote (file));
return;
}
if (user)
{
if (group)
{
spec = xmalloc (strlen (user) + 1 + strlen (group) + 1);
stpcpy (stpcpy (stpcpy (spec, user), ":"), group);
spec_allocated = 1;
}
else
{
spec = (char *) user;
}
}
else
{
spec = (char *) group;
}
switch (changed)
{
case CH_SUCCEEDED:
fmt = (user
? _("changed ownership of %s to %s\n")
: _("changed group of %s to %s\n"));
break;
case CH_FAILED:
fmt = (user
? _("failed to change ownership of %s to %s\n")
: _("failed to change group of %s to %s\n"));
break;
case CH_NO_CHANGE_REQUESTED:
fmt = (user
? _("ownership of %s retained as %s\n")
: _("group of %s retained as %s\n"));
break;
default:
abort ();
}
printf (fmt, quote (file), spec);
if (spec_allocated)
free (spec);
}
/* Recursively change the ownership of the files in directory DIR to user-id,
UID, and group-id, GID, according to the options specified by CHOPT.
STATP points to the results of lstat on DIR.
Return 0 if successful, 1 if errors occurred. */
static int
change_dir_owner (const char *dir, uid_t uid, gid_t gid,
uid_t old_uid, gid_t old_gid,
const struct stat *statp,
struct Chown_option const *chopt)
{
char *name_space, *namep;
char *path; /* Full path of each entry to process. */
unsigned dirlength; /* Length of `dir' and '\0'. */
unsigned filelength; /* Length of each pathname to process. */
unsigned pathlength; /* Bytes allocated for `path'. */
int errors = 0;
name_space = savedir (dir, statp->st_size);
if (name_space == NULL)
{
if (chopt->force_silent == 0)
error (0, errno, "%s", quote (dir));
return 1;
}
dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
pathlength = dirlength + 1;
/* Give `path' a dummy value; it will be reallocated before first use. */
path = xmalloc (pathlength);
strcpy (path, dir);
path[dirlength - 1] = '/';
for (namep = name_space; *namep; namep += filelength - dirlength)
{
filelength = dirlength + strlen (namep) + 1;
if (filelength > pathlength)
{
pathlength = filelength * 2;
path = xrealloc (path, pathlength);
}
strcpy (path + dirlength, namep);
errors |= change_file_owner (0, path, uid, gid, old_uid, old_gid,
chopt);
}
free (path);
free (name_space);
return errors;
}
/* Change the ownership of FILE to user-id, UID, and group-id, GID,
provided it presently has owner OLD_UID and group OLD_GID.
Honor the options specified by CHOPT.
If FILE is a directory and -R is given, recurse.
Return 0 if successful, 1 if errors occurred. */
int
change_file_owner (int cmdline_arg, const char *file, uid_t uid, gid_t gid,
uid_t old_uid, gid_t old_gid,
struct Chown_option const *chopt)
{
struct stat file_stats;
uid_t new_uid;
gid_t new_gid;
int errors = 0;
int is_symlink;
int is_directory;
if (lstat (file, &file_stats))
{
if (chopt->force_silent == 0)
error (0, errno, _("getting attributes of %s"), quote (file));
return 1;
}
/* If it's a symlink and we're dereferencing, then use stat
to get the attributes of the referent. */
if (S_ISLNK (file_stats.st_mode))
{
if (chopt->dereference == DEREF_ALWAYS
&& stat (file, &file_stats))
{
if (chopt->force_silent == 0)
error (0, errno, _("getting attributes of %s"), quote (file));
return 1;
}
is_symlink = 1;
/* With -R, don't traverse through symlinks-to-directories.
But of course, this will all change with POSIX's new
-H, -L, -P options. */
is_directory = 0;
}
else
{
is_symlink = 0;
is_directory = S_ISDIR (file_stats.st_mode);
}
if ((old_uid == (uid_t) -1 || file_stats.st_uid == old_uid)
&& (old_gid == (gid_t) -1 || file_stats.st_gid == old_gid))
{
new_uid = (uid == (uid_t) -1 ? file_stats.st_uid : uid);
new_gid = (gid == (gid_t) -1 ? file_stats.st_gid : gid);
if (new_uid != file_stats.st_uid || new_gid != file_stats.st_gid)
{
int fail;
int symlink_changed = 1;
int saved_errno;
int called_lchown = 0;
if (is_symlink)
{
if (chopt->dereference == DEREF_NEVER)
{
called_lchown = 1;
fail = lchown (file, new_uid, new_gid);
/* Ignore the failure if it's due to lack of support (ENOSYS)
and this is not a command line argument. */
if (!cmdline_arg && fail && errno == ENOSYS)
{
fail = 0;
symlink_changed = 0;
}
}
else if (chopt->dereference == DEREF_ALWAYS)
{
/* Applying chown to a symlink and expecting it to affect
the referent is not portable. So instead, open the
file and use fchown on the resulting descriptor. */
int fd = open (file, O_RDONLY | O_NONBLOCK | O_NOCTTY);
fail = (fd == -1 ? 1 : fchown (fd, new_uid, new_gid));
}
else
{
/* FIXME */
abort ();
}
}
else
{
fail = chown (file, new_uid, new_gid);
}
saved_errno = errno;
if (chopt->verbosity == V_high
|| (chopt->verbosity == V_changes_only && !fail))
{
enum Change_status ch_status = (! symlink_changed
? CH_NOT_APPLIED
: (fail
? CH_FAILED : CH_SUCCEEDED));
describe_change (file, ch_status,
chopt->user_name, chopt->group_name);
}
if (fail)
{
if (chopt->force_silent == 0)
error (0, saved_errno, (uid != (uid_t) -1
? _("changing ownership of %s")
: _("changing group of %s")),
quote (file));
errors = 1;
}
else
{
/* The change succeeded. On some systems, the chown function
resets the `special' permission bits. When run by a
`privileged' user, this program must ensure that at least
the set-uid and set-group ones are still set. */
if (file_stats.st_mode & ~(S_IFMT | S_IRWXUGO)
/* If we called lchown above (which means this is a symlink),
then skip it. */
&& ! called_lchown)
{
if (chmod (file, file_stats.st_mode))
{
error (0, saved_errno,
_("unable to restore permissions of %s"),
quote (file));
fail = 1;
}
}
}
}
else if (chopt->verbosity == V_high)
{
describe_change (file, CH_NO_CHANGE_REQUESTED,
chopt->user_name, chopt->group_name);
}
}
if (chopt->recurse && is_directory)
errors |= change_dir_owner (file, uid, gid,
old_uid, old_gid, &file_stats, chopt);
return errors;
}

89
src/chown-core.h Normal file
View File

@@ -0,0 +1,89 @@
/* chown-core.h -- types and prototypes shared by chown and chgrp.
Copyright (C) 2000 Free Software Foundation.
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 Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef CHOWN_CORE_H
# define CHOWN_CORE_H
enum Change_status
{
CH_NOT_APPLIED = 1,
CH_SUCCEEDED,
CH_FAILED,
CH_NO_CHANGE_REQUESTED
};
enum Verbosity
{
/* Print a message for each file that is processed. */
V_high,
/* Print a message for each file whose attributes we change. */
V_changes_only,
/* Do not be verbose. This is the default. */
V_off
};
enum Dereference_symlink
{
DEREF_UNDEFINED = 1,
DEREF_NEVER, /* -P */
DEREF_COMMAND_LINE_ARGUMENTS, /* -H */
DEREF_ALWAYS /* -L */
};
struct Chown_option
{
/* Level of verbosity. */
enum Verbosity verbosity;
/* If nonzero, change the ownership of directories recursively. */
int recurse;
/* This is useful only on systems with support for changing the
ownership of symbolic links. */
enum Dereference_symlink dereference;
/* If nonzero, force silence (no error messages). */
int force_silent;
/* The name of the user to which ownership of the files is being given. */
char *user_name;
/* The name of the group to which ownership of the files is being given. */
char *group_name;
};
void
chopt_init (struct Chown_option *);
void
chopt_free (struct Chown_option *);
char *
gid_to_name (gid_t);
char *
uid_to_name (uid_t);
int
change_file_owner PARAMS ((int, const char *,
uid_t, gid_t,
uid_t, gid_t,
struct Chown_option const *));
#endif /* CHOWN_CORE_H */

View File

@@ -31,8 +31,6 @@
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <getopt.h>
#include "system.h"
@@ -40,6 +38,7 @@
#include "lchown.h"
#include "quote.h"
#include "savedir.h"
#include "chown-core.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "chown"
@@ -59,52 +58,9 @@ struct group *getgrgid ();
char *parse_user_spec ();
void strip_trailing_slashes ();
enum Change_status
{
CH_NOT_APPLIED,
CH_SUCCEEDED,
CH_FAILED,
CH_NO_CHANGE_REQUESTED
};
enum Verbosity
{
/* Print a message for each file that is processed. */
V_high,
/* Print a message for each file whose attributes we change. */
V_changes_only,
/* Do not be verbose. This is the default. */
V_off
};
static int change_dir_owner PARAMS ((const char *dir, uid_t user, gid_t group,
uid_t old_user, gid_t old_group,
const struct stat *statp));
/* The name the program was run with. */
char *program_name;
/* If nonzero, and the systems has support for it, change the ownership
of symbolic links rather than any files they point to. */
static int change_symlinks = 1;
/* If nonzero, change the ownership of directories recursively. */
static int recurse;
/* If nonzero, force silence (no error messages). */
static int force_silent;
/* Level of verbosity. */
static enum Verbosity verbosity = V_off;
/* The name of the user to which ownership of the files is being given. */
static char *username;
/* The name of the group to which ownership of the files is being given. */
static const char *groupname;
/* The argument to the --reference option. Use the owner and group IDs
of this file. This file must exist. */
static char *reference_file;
@@ -134,169 +90,6 @@ static struct option const long_options[] =
{0, 0, 0, 0}
};
/* Tell the user how/if the user and group of FILE have been changed.
CHANGED describes what (if anything) has happened. */
static void
describe_change (const char *file, enum Change_status changed)
{
const char *fmt;
if (changed == CH_NOT_APPLIED)
{
printf (_("neither symbolic link %s nor referent has been changed\n"),
quote (file));
return;
}
switch (changed)
{
case CH_SUCCEEDED:
fmt = _("owner of %s changed to ");
break;
case CH_FAILED:
fmt = _("failed to change owner of %s to ");
break;
case CH_NO_CHANGE_REQUESTED:
fmt = _("owner of %s retained as ");
break;
default:
abort ();
}
printf (fmt, file);
if (groupname)
printf ("%s.%s\n", username, groupname);
else
printf ("%s\n", username);
}
/* Change the ownership of FILE to UID USER and GID GROUP
provided it presently has UID OLDUSER and GID OLDGROUP.
If it is a directory and -R is given, recurse.
Return 0 if successful, 1 if errors occurred. */
static int
change_file_owner (int cmdline_arg, const char *file, uid_t user, gid_t group,
uid_t old_user, gid_t old_group)
{
struct stat file_stats;
uid_t newuser;
gid_t newgroup;
int errors = 0;
if (lstat (file, &file_stats))
{
if (force_silent == 0)
error (0, errno, _("getting attributes of %s"), quote (file));
return 1;
}
if ((old_user == (uid_t) -1 || file_stats.st_uid == old_user) &&
(old_group == (gid_t) -1 || file_stats.st_gid == old_group))
{
newuser = user == (uid_t) -1 ? file_stats.st_uid : user;
newgroup = group == (gid_t) -1 ? file_stats.st_gid : group;
if (newuser != file_stats.st_uid || newgroup != file_stats.st_gid)
{
int fail;
int symlink_changed = 1;
int saved_errno;
if (S_ISLNK (file_stats.st_mode) && change_symlinks)
{
fail = lchown (file, newuser, newgroup);
/* Ignore the failure if it's due to lack of support (ENOSYS)
and this is not a command line argument. */
if (!cmdline_arg && fail && errno == ENOSYS)
{
fail = 0;
symlink_changed = 0;
}
}
else
{
fail = chown (file, newuser, newgroup);
}
saved_errno = errno;
if (verbosity == V_high || (verbosity == V_changes_only && !fail))
{
enum Change_status ch_status = (! symlink_changed
? CH_NOT_APPLIED
: (fail
? CH_FAILED : CH_SUCCEEDED));
describe_change (file, ch_status);
}
if (fail)
{
if (force_silent == 0)
error (0, saved_errno, _("changing ownership of %s"),
quote (file));
errors = 1;
}
}
else if (verbosity == V_high)
{
describe_change (file, CH_NO_CHANGE_REQUESTED);
}
}
if (recurse && S_ISDIR (file_stats.st_mode))
errors |= change_dir_owner (file, user, group,
old_user, old_group, &file_stats);
return errors;
}
/* Recursively change the ownership of the files in directory DIR
to UID USER and GID GROUP.
STATP points to the results of lstat on DIR.
Return 0 if successful, 1 if errors occurred. */
static int
change_dir_owner (const char *dir, uid_t user, gid_t group,
uid_t old_user, gid_t old_group,
const struct stat *statp)
{
char *name_space, *namep;
char *path; /* Full path of each entry to process. */
unsigned dirlength; /* Length of `dir' and '\0'. */
unsigned filelength; /* Length of each pathname to process. */
unsigned pathlength; /* Bytes allocated for `path'. */
int errors = 0;
name_space = savedir (dir, statp->st_size);
if (name_space == NULL)
{
if (force_silent == 0)
error (0, errno, "%s", quote (dir));
return 1;
}
dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
pathlength = dirlength + 1;
/* Give `path' a dummy value; it will be reallocated before first use. */
path = xmalloc (pathlength);
strcpy (path, dir);
path[dirlength - 1] = '/';
for (namep = name_space; *namep; namep += filelength - dirlength)
{
filelength = dirlength + strlen (namep) + 1;
if (filelength > pathlength)
{
pathlength = filelength * 2;
path = xrealloc (path, pathlength);
}
strcpy (path + dirlength, namep);
errors |= change_file_owner (0, path, user, group, old_user, old_group);
}
free (path);
free (name_space);
return errors;
}
void
usage (int status)
{
@@ -345,10 +138,11 @@ as symbolic.\n\
int
main (int argc, char **argv)
{
uid_t user = (uid_t) -1; /* New uid; -1 if not to be changed. */
gid_t group = (uid_t) -1; /* New gid; -1 if not to be changed. */
uid_t old_user = (uid_t) -1; /* Old uid; -1 if unrestricted. */
gid_t old_group = (uid_t) -1; /* Old gid; -1 if unrestricted. */
uid_t uid = (uid_t) -1; /* New uid; -1 if not to be changed. */
gid_t gid = (uid_t) -1; /* New gid; -1 if not to be changed. */
uid_t old_uid = (uid_t) -1; /* Old uid; -1 if unrestricted. */
gid_t old_gid = (uid_t) -1; /* Old gid; -1 if unrestricted. */
struct Chown_option chopt;
int errors = 0;
int optc;
@@ -360,7 +154,7 @@ main (int argc, char **argv)
atexit (close_stdout);
recurse = force_silent = 0;
chopt_init (&chopt);
while ((optc = getopt_long (argc, argv, "Rcfhv", long_options, NULL)) != -1)
{
@@ -372,32 +166,32 @@ main (int argc, char **argv)
reference_file = optarg;
break;
case DEREFERENCE_OPTION:
change_symlinks = 0;
chopt.dereference = DEREF_ALWAYS;
break;
case FROM_OPTION:
{
char *u_dummy, *g_dummy;
const char *e = parse_user_spec (argv[optind],
&old_user, &old_group,
&old_uid, &old_gid,
&u_dummy, &g_dummy);
if (e)
error (1, 0, "%s: %s", quote (argv[optind]), e);
break;
}
case 'R':
recurse = 1;
chopt.recurse = 1;
break;
case 'c':
verbosity = V_changes_only;
chopt.verbosity = V_changes_only;
break;
case 'f':
force_silent = 1;
chopt.force_silent = 1;
break;
case 'h':
change_symlinks = 1;
chopt.dereference = DEREF_NEVER;
break;
case 'v':
verbosity = V_high;
chopt.verbosity = V_high;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -419,17 +213,21 @@ main (int argc, char **argv)
if (stat (reference_file, &ref_stats))
error (1, errno, _("getting attributes of %s"), quote (reference_file));
user = ref_stats.st_uid;
group = ref_stats.st_gid;
uid = ref_stats.st_uid;
gid = ref_stats.st_gid;
chopt.user_name = uid_to_name (ref_stats.st_uid);
chopt.group_name = gid_to_name (ref_stats.st_gid);
}
else
{
const char *e = parse_user_spec (argv[optind], &user, &group,
&username, &groupname);
const char *e = parse_user_spec (argv[optind], &uid, &gid,
&chopt.user_name, &chopt.group_name);
if (e)
error (1, 0, "%s: %s", argv[optind], e);
if (username == NULL)
username = "";
/* FIXME: set it to the empty string? */
if (chopt.user_name == NULL)
chopt.user_name = "";
optind++;
}
@@ -437,9 +235,11 @@ main (int argc, char **argv)
for (; optind < argc; ++optind)
{
strip_trailing_slashes (argv[optind]);
errors |= change_file_owner (1, argv[optind], user, group,
old_user, old_group);
errors |= change_file_owner (1, argv[optind], uid, gid,
old_uid, old_gid, &chopt);
}
chopt_free (&chopt);
exit (errors);
}

View File

@@ -103,15 +103,9 @@ static size_t conversion_blocksize = 0;
/* Skip this many records of `input_blocksize' bytes before input. */
static uintmax_t skip_records = 0;
/* Nonzero if SKIP_RECORDS is actually a byte count, not a record count. */
static int skip_bytes = 0;
/* Skip this many records of `output_blocksize' bytes before output. */
static uintmax_t seek_records = 0;
/* Nonzero if SEEK_RECORDS is actually a byte count, not a record count. */
static int seek_bytes = 0;
/* Copy only this many records. The default is effectively infinity. */
static uintmax_t max_records = (uintmax_t) -1;
@@ -311,7 +305,6 @@ Copy a file, converting and formatting according to the options.\n\
BLOCKS and BYTES may be followed by the following multiplicative suffixes:\n\
xM M, c 1, w 2, b 512, kD 1000, k 1024, MD 1,000,000, M 1,048,576,\n\
GD 1,000,000,000, G 1,073,741,824, and so on for T, P, E, Z, Y.\n\
For seek= and skip=, a B suffix for BLOCKS means it counts bytes not blocks.\n\
Each KEYWORD may be:\n\
\n\
ascii from EBCDIC to ASCII\n\
@@ -566,18 +559,7 @@ scanargs (int argc, char **argv)
else
{
int invalid = 0;
uintmax_t n;
int count_bytes = 0;
if (STREQ (name, "seek") || STREQ (name, "skip"))
{
size_t vallen = strlen (val);
count_bytes = vallen && val[vallen - 1] == 'B';
if (count_bytes)
val[vallen - 1] = '\0';
}
n = parse_integer (val, &invalid);
uintmax_t n = parse_integer (val, &invalid);
if (STREQ (name, "ibs"))
{
@@ -603,15 +585,9 @@ scanargs (int argc, char **argv)
|| conversion_blocksize == 0);
}
else if (STREQ (name, "skip"))
{
skip_records = n;
skip_bytes = count_bytes;
}
skip_records = n;
else if (STREQ (name, "seek"))
{
seek_records = n;
seek_bytes = count_bytes;
}
seek_records = n;
else if (STREQ (name, "count"))
max_records = n;
else
@@ -783,32 +759,23 @@ buggy_lseek_support (int fdesc)
nonzero. */
static void
skip (int fdesc, char *file, int count_bytes, uintmax_t records,
size_t blocksize, unsigned char *buf)
skip (int fdesc, char *file, uintmax_t records, size_t blocksize,
unsigned char *buf)
{
size_t seek_blocksize = count_bytes ? 1 : blocksize;
off_t offset = records * seek_blocksize;
off_t offset = records * blocksize;
/* Try lseek and if an error indicates it was an inappropriate
operation, fall back on using read. Some broken versions of
lseek may return zero, so count that as an error too as a valid
zero return is not possible here. */
if (offset / seek_blocksize != records
if (offset / blocksize != records
|| buggy_lseek_support (fdesc)
|| lseek (fdesc, offset, SEEK_CUR) <= 0)
{
if (count_bytes)
records = offset;
while (records)
while (records--)
{
int nread;
if (count_bytes && records < blocksize)
blocksize = records;
nread = safe_read (fdesc, buf, blocksize);
ssize_t nread = safe_read (fdesc, buf, blocksize);
if (nread < 0)
{
error (0, errno, _("reading %s"), quote (file));
@@ -819,8 +786,6 @@ skip (int fdesc, char *file, int count_bytes, uintmax_t records,
FIXME: maybe give a warning. */
if (nread == 0)
break;
records -= (count_bytes ? nread : 1);
}
}
}
@@ -927,7 +892,7 @@ dd_copy (void)
unsigned char *ibuf, *bufstart; /* Input buffer. */
unsigned char *real_buf; /* real buffer address before alignment */
unsigned char *real_obuf;
int nread; /* Bytes read in the current block. */
ssize_t nread; /* Bytes read in the current block. */
int exit_status = 0;
size_t page_size = getpagesize ();
size_t n_bytes_read;
@@ -970,8 +935,7 @@ dd_copy (void)
}
if (skip_records != 0)
skip (STDIN_FILENO, input_file, skip_bytes, skip_records,
input_blocksize, ibuf);
skip (STDIN_FILENO, input_file, skip_records, input_blocksize, ibuf);
if (seek_records != 0)
{
@@ -982,8 +946,7 @@ dd_copy (void)
0+0 records out
*/
skip (STDOUT_FILENO, output_file, seek_bytes, seek_records,
output_blocksize, obuf);
skip (STDOUT_FILENO, output_file, seek_records, output_blocksize, obuf);
}
if (max_records == 0)
@@ -1028,7 +991,7 @@ dd_copy (void)
}
}
n_bytes_read = (size_t) nread;
n_bytes_read = nread;
if (n_bytes_read < input_blocksize)
{
@@ -1190,9 +1153,8 @@ main (int argc, char **argv)
if (seek_records != 0 && !(conversions_mask & C_NOTRUNC))
{
struct stat stdout_stat;
size_t blocksize = seek_bytes ? 1 : output_blocksize;
off_t o = seek_records * blocksize;
if (o / blocksize != seek_records)
off_t o = seek_records * output_blocksize;
if (o / output_blocksize != seek_records)
error (1, 0, _("file offset out of range"));
if (fstat (STDOUT_FILENO, &stdout_stat) != 0)

View File

@@ -26,6 +26,7 @@
#include "error.h"
#include "dirname.h"
#include "closeout.h"
#include "xalloc.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "dirname"
@@ -92,9 +93,11 @@ main (int argc, char **argv)
usage (1);
}
len = dir_name_r (argv[1], &result);
fwrite (result, 1, len, stdout);
putchar ('\n');
result = dir_name (argv[1]);
if (result == NULL)
xalloc_die ();
puts (result);
free (result);
exit (0);
}

View File

@@ -54,21 +54,9 @@ static void print_full_info PARAMS ((const char *username));
/* The name this program was run with. */
char *program_name;
/* If nonzero, output only the group ID(s). -g */
static int just_group = 0;
/* If nonzero, output user/group name instead of ID number. -n */
static int use_name = 0;
/* If nonzero, output real UID/GID instead of default effective UID/GID. -r */
static int use_real = 0;
/* If nonzero, output only the user ID(s). -u */
static int just_user = 0;
/* If nonzero, output only the supplementary groups. -G */
static int just_group_list = 0;
/* The real and effective IDs of the user to print. */
static uid_t ruid, euid;
static gid_t rgid, egid;
@@ -101,11 +89,11 @@ usage (int status)
Print information for USERNAME, or the current user.\n\
\n\
-a ignore, for compatibility with other versions\n\
-g, --group print only the group ID\n\
-G, --groups print only the supplementary groups\n\
-g, --group print only the effective group ID\n\
-G, --groups print all group IDs\n\
-n, --name print a name instead of a number, for -ugG\n\
-r, --real print the real ID instead of effective ID, for -ugG\n\
-u, --user print only the user ID\n\
-r, --real print the real ID instead of the effective ID, with -ugG\n\
-u, --user print only the effective user ID\n\
--help display this help and exit\n\
--version output version information and exit\n\
\n\
@@ -121,6 +109,15 @@ main (int argc, char **argv)
{
int optc;
/* If nonzero, output the list of all group IDs. -G */
int just_group_list = 0;
/* If nonzero, output only the group ID(s). -g */
int just_group = 0;
/* If nonzero, output real UID/GID instead of default effective UID/GID. -r */
int use_real = 0;
/* If nonzero, output only the user ID(s). -u */
int just_user = 0;
program_name = argv[0];
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);

View File

@@ -1887,23 +1887,9 @@ gobble_file (const char *name, enum filetype type, int explicit_arg,
attach (path, dirname, name);
}
if (trace_links)
{
val = stat (path, &files[files_index].stat);
if (val < 0)
{
/* Perhaps a symbolically-linked to file doesn't exist; stat
the link instead. */
val = lstat (path, &files[files_index].stat);
}
}
else
{
val = lstat (path, &files[files_index].stat);
#if USE_ACL
files[files_index].have_acl = (acl (path, GETACLCNT, 0, NULL) > 4);
#endif
}
val = (trace_links
? stat (path, &files[files_index].stat)
: lstat (path, &files[files_index].stat));
if (val < 0)
{
@@ -1912,6 +1898,12 @@ gobble_file (const char *name, enum filetype type, int explicit_arg,
return 0;
}
#if USE_ACL
files[files_index].have_acl =
(! S_ISLNK (files[files_index].stat.st_mode)
&& 4 < acl (path, GETACLCNT, 0, NULL));
#endif
if (S_ISLNK (files[files_index].stat.st_mode)
&& (explicit_arg || format == long_format || check_symlink_color))
{

View File

@@ -143,23 +143,19 @@ main (int argc, char **argv)
for (; optind < argc; ++optind)
{
int fail = 0;
/* Remove any trailing slashes. Not removing them would lead to calling
`mkdir ("dir/", mode)' for e.g., the commands `mkdir dir/' and
`mkdir -p dir/', and such a call fails on NetBSD systems when `dir'
doesn't already exist. */
strip_trailing_slashes (argv[optind]);
if (create_parents)
{
char *parents = dir_name (argv[optind]);
fail = make_path (parents, parent_mode, parent_mode,
-1, -1, 1, verbose_fmt_string);
free (parents);
/* If we're creating parent directories, then it's ok to remove
trailing slashes. In fact, *not* removing them would lead
to calling `mkdir ("dir/", mode)' for the command `mkdir -p dir/',
and such a call fails on NetBSD systems if `dir' doesn't already
exist. */
/* An alternate approach would be to change make_path to interpret
an argument with a trailing slash as if it also had a trailing
`.'. In fact, that would be more consistent with POSIX, so
FIXME: some day. */
strip_trailing_slashes (argv[optind]);
}
if (fail == 0)

310
src/od.c
View File

@@ -65,11 +65,6 @@ typedef double LONG_DOUBLE;
# define LDBL_DIG DBL_DIG
#endif
#if !HAVE_FSEEKO
# undef fseeko
# define fseeko(Stream, Offset, Whence) (-1)
#endif
enum size_spec
{
NO_SIZE,
@@ -155,19 +150,18 @@ static const char *const charname[33] =
"sp"
};
/* A printf control string for printing a file offset. */
static const char *output_address_fmt_string;
/* Address base (8, 10 or 16). */
static int address_base;
/* FIXME: make this the number of octal digits in an unsigned long. */
#define MAX_ADDRESS_LENGTH 13
/* The number of octal digits required to represent the largest off_t value. */
#define MAX_ADDRESS_LENGTH \
((sizeof (off_t) * CHAR_BIT + CHAR_BIT - 1) / 3)
/* Space for a normal address, a space, a pseudo address, parentheses
around the pseudo address, and a trailing zero byte. */
static char address_fmt_buffer[2 * MAX_ADDRESS_LENGTH + 4];
static char address_pad[MAX_ADDRESS_LENGTH + 1];
/* Width of a normal address. */
static int address_pad_len;
static unsigned long int string_min;
static unsigned long int flag_dump_strings;
static size_t string_min;
static int flag_dump_strings;
/* Non-zero if we should recognize the pre-POSIX non-option arguments
that specified at most one file and optional arguments specifying
@@ -175,15 +169,15 @@ static unsigned long int flag_dump_strings;
static int traditional;
/* Non-zero if an old-style `pseudo-address' was specified. */
static long int flag_pseudo_start;
static int flag_pseudo_start;
/* The difference between the old-style pseudo starting address and
the number of bytes to skip. */
static long int pseudo_offset;
static off_t pseudo_offset;
/* Function to format an address and optionally an additional parenthesized
pseudo-address; it returns the formatted string. */
static const char *(*format_address) PARAMS ((long unsigned int));
/* Function that accepts an address and an optional following char,
and prints the address and char to stdout. */
static void (*format_address) PARAMS ((off_t, char));
/* The number of input bytes to skip before formatting and writing. */
static off_t n_bytes_to_skip = 0;
@@ -205,16 +199,16 @@ static int abbreviate_duplicate_blocks = 1;
static struct tspec *spec;
/* The number of format specs. */
static unsigned int n_specs;
static size_t n_specs;
/* The allocated length of SPEC. */
static unsigned int n_specs_allocated;
static size_t n_specs_allocated;
/* The number of input bytes formatted per output line. It must be
a multiple of the least common multiple of the sizes associated with
the specified output types. It should be as large as possible, but
no larger than 16 -- unless specified with the -w option. */
static unsigned int bytes_per_block;
static size_t bytes_per_block;
/* Human-readable representation of *file_list (for error messages).
It differs from *file_list only when *file_list is "-". */
@@ -364,10 +358,9 @@ lcm (unsigned int u, unsigned int v)
}
static void
print_s_char (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_s_char (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes; i > 0; i--)
{
int tmp = (unsigned) *(const unsigned char *) block;
@@ -380,10 +373,9 @@ print_s_char (long unsigned int n_bytes, const char *block,
}
static void
print_char (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_char (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes; i > 0; i--)
{
unsigned int tmp = *(const unsigned char *) block;
@@ -393,10 +385,9 @@ print_char (long unsigned int n_bytes, const char *block,
}
static void
print_s_short (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_s_short (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes / sizeof (unsigned short); i > 0; i--)
{
int tmp = (unsigned) *(const unsigned short *) block;
@@ -409,10 +400,9 @@ print_s_short (long unsigned int n_bytes, const char *block,
}
static void
print_short (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_short (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes / sizeof (unsigned short); i > 0; i--)
{
unsigned int tmp = *(const unsigned short *) block;
@@ -422,10 +412,9 @@ print_short (long unsigned int n_bytes, const char *block,
}
static void
print_int (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_int (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes / sizeof (unsigned int); i > 0; i--)
{
unsigned int tmp = *(const unsigned int *) block;
@@ -435,10 +424,9 @@ print_int (long unsigned int n_bytes, const char *block,
}
static void
print_long (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_long (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes / sizeof (unsigned long); i > 0; i--)
{
unsigned long tmp = *(const unsigned long *) block;
@@ -449,10 +437,9 @@ print_long (long unsigned int n_bytes, const char *block,
#ifdef HAVE_UNSIGNED_LONG_LONG
static void
print_long_long (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_long_long (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes / sizeof (unsigned long long); i > 0; i--)
{
unsigned long long tmp = *(const unsigned long long *) block;
@@ -463,10 +450,9 @@ print_long_long (long unsigned int n_bytes, const char *block,
#endif
static void
print_float (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_float (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes / sizeof (float); i > 0; i--)
{
float tmp = *(const float *) block;
@@ -476,10 +462,9 @@ print_float (long unsigned int n_bytes, const char *block,
}
static void
print_double (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_double (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes / sizeof (double); i > 0; i--)
{
double tmp = *(const double *) block;
@@ -490,10 +475,9 @@ print_double (long unsigned int n_bytes, const char *block,
#ifdef HAVE_LONG_DOUBLE
static void
print_long_double (long unsigned int n_bytes, const char *block,
const char *fmt_string)
print_long_double (off_t n_bytes, const char *block, const char *fmt_string)
{
int i;
off_t i;
for (i = n_bytes / sizeof (LONG_DOUBLE); i > 0; i--)
{
LONG_DOUBLE tmp = *(const LONG_DOUBLE *) block;
@@ -505,9 +489,9 @@ print_long_double (long unsigned int n_bytes, const char *block,
#endif
static void
dump_hexl_mode_trailer (long unsigned int n_bytes, const char *block)
dump_hexl_mode_trailer (off_t n_bytes, const char *block)
{
int i;
off_t i;
fputs (" >", stdout);
for (i = n_bytes; i > 0; i--)
{
@@ -520,10 +504,10 @@ dump_hexl_mode_trailer (long unsigned int n_bytes, const char *block)
}
static void
print_named_ascii (long unsigned int n_bytes, const char *block,
const char *unused_fmt_string)
print_named_ascii (off_t n_bytes, const char *block,
const char *unused_fmt_string ATTRIBUTE_UNUSED)
{
int i;
off_t i;
for (i = n_bytes; i > 0; i--)
{
unsigned int c = *(const unsigned char *) block;
@@ -547,10 +531,10 @@ print_named_ascii (long unsigned int n_bytes, const char *block,
}
static void
print_ascii (long unsigned int n_bytes, const char *block,
const char *unused_fmt_string)
print_ascii (off_t n_bytes, const char *block,
const char *unused_fmt_string ATTRIBUTE_UNUSED)
{
int i;
off_t i;
for (i = n_bytes; i > 0; i--)
{
unsigned int c = *(const unsigned char *) block;
@@ -652,7 +636,7 @@ decode_one_format (const char *s_orig, const char *s, const char **next,
enum output_format fmt;
const char *pre_fmt_string;
char *fmt_string;
void (*print_function) ();
void (*print_function) PARAMS ((off_t, const char *, const char *));
const char *p;
unsigned int c;
unsigned int field_width = 0;
@@ -702,7 +686,7 @@ decode_one_format (const char *s_orig, const char *s, const char **next,
size = sizeof (int);
else
{
if (size > MAX_INTEGRAL_TYPE_SIZE
if (MAX_INTEGRAL_TYPE_SIZE < size
|| integral_type_size[size] == NO_SIZE)
{
error (0, 0, _("invalid type string `%s';\n\
@@ -986,15 +970,15 @@ skip (off_t n_skip)
if (n_skip == 0)
break;
/* First try using fseek. For large offsets, this extra work is
/* First try seeking. For large offsets, this extra work is
worthwhile. If the offset is below some threshold it may be
more efficient to move the pointer by reading. There are two
issues when trying to use fseek:
issues when trying to seek:
- the file must be seekable.
- before seeking to the specified position, make sure
that the new position is in the current file.
Try to do that by getting file's size using fstat().
But that will work only for regular files and dirs. */
Try to do that by getting file's size using fstat.
But that will work only for regular files. */
if (fstat (fileno (in_stream), &file_stats))
{
@@ -1010,7 +994,7 @@ skip (off_t n_skip)
n_skip and go on to the next file. */
if (S_ISREG (file_stats.st_mode))
{
if (n_skip >= file_stats.st_size)
if (file_stats.st_size <= n_skip)
{
n_skip -= file_stats.st_size;
if (in_stream != stdin && fclose (in_stream) == EOF)
@@ -1022,10 +1006,7 @@ skip (off_t n_skip)
}
else
{
/* Try fseeko if available, fseek otherwise. */
if (fseeko (in_stream, n_skip, SEEK_SET) == 0
|| (n_skip <= LONG_MAX
&& fseek (in_stream, (long) n_skip, SEEK_SET) == 0))
if (0 <= lseek (fileno (in_stream), n_skip, SEEK_CUR))
{
n_skip = 0;
break;
@@ -1036,10 +1017,10 @@ skip (off_t n_skip)
/* Seek didn't work or wasn't attempted; position the file pointer
by reading. */
for (j = n_skip / BUFSIZ; j >= 0; j--)
for (j = n_skip / BUFSIZ; 0 <= j; j--)
{
char buf[BUFSIZ];
size_t n_bytes_to_read = (j > 0
size_t n_bytes_to_read = (0 < j
? BUFSIZ
: n_skip % BUFSIZ);
size_t n_bytes_read;
@@ -1059,32 +1040,64 @@ skip (off_t n_skip)
return err;
}
static const char *
format_address_none (long unsigned int address)
static void
format_address_none (off_t address ATTRIBUTE_UNUSED, char c ATTRIBUTE_UNUSED)
{
return "";
}
static const char *
format_address_std (long unsigned int address)
static void
format_address_std (off_t address, char c)
{
const char *address_string;
char buf[MAX_ADDRESS_LENGTH + 2];
char *p = buf + sizeof buf;
char const *pbound;
sprintf (address_fmt_buffer, output_address_fmt_string, address);
address_string = address_fmt_buffer;
return address_string;
*--p = '\0';
*--p = c;
pbound = p - address_pad_len;
/* Use a special case of the code for each base. This is measurably
faster than generic code. */
switch (address_base)
{
case 8:
do
*--p = '0' + (address & 7);
while ((address >>= 3) != 0);
break;
case 10:
do
*--p = '0' + (address % 10);
while ((address /= 10) != 0);
break;
case 16:
do
*--p = "0123456789abcdef"[address & 15];
while ((address >>= 4) != 0);
break;
}
while (pbound < p)
*--p = '0';
fputs (p, stdout);
}
static const char *
format_address_label (long unsigned int address)
static void
format_address_paren (off_t address, char c)
{
const char *address_string;
assert (output_address_fmt_string != NULL);
putchar ('(');
format_address_std (address, ')');
putchar (c);
}
sprintf (address_fmt_buffer, output_address_fmt_string,
address, address + pseudo_offset);
address_string = address_fmt_buffer;
return address_string;
static void
format_address_label (off_t address, char c)
{
format_address_std (address, ' ');
format_address_paren (address + pseudo_offset, c);
}
/* Write N_BYTES bytes from CURR_BLOCK to standard output once for each
@@ -1099,7 +1112,7 @@ format_address_label (long unsigned int address)
only when it has not been padded to length BYTES_PER_BLOCK. */
static void
write_block (long unsigned int current_offset, long unsigned int n_bytes,
write_block (off_t current_offset, off_t n_bytes,
const char *prev_block, const char *curr_block)
{
static int first = 1;
@@ -1124,16 +1137,15 @@ write_block (long unsigned int current_offset, long unsigned int n_bytes,
}
else
{
unsigned int i;
size_t i;
prev_pair_equal = 0;
for (i = 0; i < n_specs; i++)
{
const char *addr_or_pad = (i == 0
? format_address (current_offset)
: address_pad);
fputs (addr_or_pad, stdout);
if (i == 0)
format_address (current_offset, '\0');
else
printf ("%*s", address_pad_len, "");
(*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
if (spec[i].hexl_mode_trailer)
{
@@ -1264,7 +1276,7 @@ read_block (size_t n, char *block, size_t *n_bytes_in_buffer)
{
int err;
assert (n > 0 && n <= bytes_per_block);
assert (0 < n && n <= bytes_per_block);
*n_bytes_in_buffer = 0;
@@ -1324,7 +1336,7 @@ read_block (size_t n, char *block, size_t *n_bytes_in_buffer)
static int
get_lcm (void)
{
unsigned int i;
size_t i;
int l_c_m = 1;
for (i = 0; i < n_specs; i++)
@@ -1341,7 +1353,7 @@ parse_old_offset (const char *s)
int radix;
off_t offset;
enum strtol_error s_err;
long unsigned int tmp;
uintmax_t tmp;
if (*s == '\0')
return -1;
@@ -1363,12 +1375,15 @@ parse_old_offset (const char *s)
radix = 8;
}
s_err = xstrtoul (s, NULL, radix, &tmp, "Bb");
s_err = xstrtoumax (s, NULL, radix, &tmp, "Bb");
if (s_err != LONGINT_OK)
{
STRTOL_FAIL_WARN (s, _("old-style offset"), s_err);
return -1;
}
if (OFF_T_MAX < tmp)
error (EXIT_FAILURE, 0,
_("%s is larger than the maximum file size on this system"), s);
offset = tmp;
return offset;
}
@@ -1450,7 +1465,7 @@ dump (void)
/* Make bytes_to_write the smallest multiple of l_c_m that
is at least as large as n_bytes_read. */
bytes_to_write = l_c_m * (int) ((n_bytes_read + l_c_m - 1) / l_c_m);
bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
memset (block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
write_block (current_offset, bytes_to_write,
@@ -1458,8 +1473,7 @@ dump (void)
current_offset += n_bytes_read;
}
if (output_address_fmt_string != NULL)
printf ("%s\n", format_address (current_offset));
format_address (current_offset, '\n');
if (limit_bytes_to_format && current_offset > end_offset)
err |= check_and_close ();
@@ -1485,15 +1499,14 @@ dump_strings (void)
err = 0;
while (1)
{
unsigned int i;
size_t i;
int c;
/* See if the next `string_min' chars are all printing chars. */
tryline:
if (limit_bytes_to_format
&& address >= (n_bytes_to_skip + max_bytes_to_format -
(off_t) string_min))
&& address >= (n_bytes_to_skip + max_bytes_to_format - string_min))
break;
for (i = 0; i < string_min; i++)
@@ -1538,10 +1551,8 @@ dump_strings (void)
/* If we get here, the string is all printable and null-terminated,
so print it. It is all in `buf' and `i' is its length. */
buf[i] = 0;
if (output_address_fmt_string != NULL)
{
printf ("%s ", format_address (address - i - 1));
}
format_address (address - i - 1, ' ');
for (i = 0; (c = buf[i]); i++)
{
switch (c)
@@ -1595,17 +1606,16 @@ main (int argc, char **argv)
{
int c;
int n_files;
unsigned int i;
unsigned int l_c_m;
unsigned int address_pad_len;
unsigned long int desired_width;
size_t i;
int l_c_m;
size_t desired_width IF_LINT (= 0);
int width_specified = 0;
int n_failed_decodes = 0;
int err;
/* The old-style `pseudo starting address' to be printed in parentheses
after any true address. */
long int pseudo_start IF_LINT (= 0);
off_t pseudo_start IF_LINT (= 0);
program_name = argv[0];
setlocale (LC_ALL, "");
@@ -1641,15 +1651,15 @@ main (int argc, char **argv)
n_specs_allocated = 5;
spec = (struct tspec *) xmalloc (n_specs_allocated * sizeof (struct tspec));
output_address_fmt_string = "%07o";
format_address = format_address_std;
address_base = 8;
address_pad_len = 7;
flag_dump_strings = 0;
while ((c = getopt_long (argc, argv, "abcdfhilos::xw::A:j:N:t:v",
long_options, NULL)) != -1)
{
unsigned long int tmp;
uintmax_t tmp;
enum strtol_error s_err;
switch (c)
@@ -1661,22 +1671,21 @@ main (int argc, char **argv)
switch (optarg[0])
{
case 'd':
output_address_fmt_string = "%07d";
format_address = format_address_std;
address_base = 10;
address_pad_len = 7;
break;
case 'o':
output_address_fmt_string = "%07o";
format_address = format_address_std;
address_base = 8;
address_pad_len = 7;
break;
case 'x':
output_address_fmt_string = "%06x";
format_address = format_address_std;
address_base = 16;
address_pad_len = 6;
break;
case 'n':
output_address_fmt_string = NULL;
format_address = format_address_none;
address_pad_len = 0;
break;
@@ -1690,7 +1699,7 @@ it must be one character from [doxn]"),
break;
case 'j':
s_err = xstrtoul (optarg, NULL, 0, &tmp, "bkm");
s_err = xstrtoumax (optarg, NULL, 0, &tmp, "bkm");
n_bytes_to_skip = tmp;
if (s_err != LONGINT_OK)
STRTOL_FATAL_ERROR (optarg, _("skip argument"), s_err);
@@ -1699,17 +1708,15 @@ it must be one character from [doxn]"),
case 'N':
limit_bytes_to_format = 1;
/* FIXME: if off_t is long long and that's an 8-byte type,
use xstrtouq here. */
s_err = xstrtoul (optarg, NULL, 0, &tmp, "bkm");
s_err = xstrtoumax (optarg, NULL, 0, &tmp, "bkm");
max_bytes_to_format = tmp;
if (s_err != LONGINT_OK)
STRTOL_FATAL_ERROR (optarg, _("limit argument"), s_err);
if (tmp > LONG_MAX)
if (OFF_T_MAX < tmp)
error (EXIT_FAILURE, 0,
_("specified number of bytes `%s' is larger than \
the maximum\nrepresentable value of type `long'"), optarg);
_("%s is larger than the maximum file size on this system"),
optarg);
break;
case 's':
@@ -1717,11 +1724,18 @@ the maximum\nrepresentable value of type `long'"), optarg);
string_min = 3;
else
{
s_err = xstrtoul (optarg, NULL, 0, &string_min, "bkm");
s_err = xstrtoumax (optarg, NULL, 0, &tmp, "bkm");
if (s_err != LONGINT_OK)
STRTOL_FATAL_ERROR (optarg, _("minimum string length"), s_err);
/* The minimum string length may be no larger than SIZE_MAX,
since we may allocate a buffer of this size. */
if (SIZE_MAX < tmp)
error (EXIT_FAILURE, 0, _("%s is too large"), optarg);
string_min = tmp;
}
++flag_dump_strings;
flag_dump_strings = 1;
break;
case 't':
@@ -1771,9 +1785,13 @@ the maximum\nrepresentable value of type `long'"), optarg);
}
else
{
s_err = xstrtoul (optarg, NULL, 10, &desired_width, "");
uintmax_t w_tmp;
s_err = xstrtoumax (optarg, NULL, 10, &w_tmp, "");
if (s_err != LONGINT_OK)
STRTOL_FATAL_ERROR (optarg, _("width specification"), s_err);
if (SIZE_MAX < w_tmp)
error (EXIT_FAILURE, 0, _("%s is too large"), optarg);
desired_width = w_tmp;
}
break;
@@ -1871,29 +1889,17 @@ the maximum\nrepresentable value of type `long'"), optarg);
if (flag_pseudo_start)
{
static char buf[10];
if (output_address_fmt_string == NULL)
if (format_address == format_address_none)
{
output_address_fmt_string = "(%07o)";
format_address = format_address_std;
address_base = 8;
address_pad_len = 7;
format_address = format_address_paren;
}
else
{
sprintf (buf, "%s (%s)",
output_address_fmt_string,
output_address_fmt_string);
output_address_fmt_string = buf;
format_address = format_address_label;
}
format_address = format_address_label;
}
}
assert (address_pad_len <= MAX_ADDRESS_LENGTH);
for (i = 0; i < address_pad_len; i++)
address_pad[i] = ' ';
address_pad[address_pad_len] = '\0';
if (n_specs == 0)
{
if (decode_one_format ("o2", "o2", NULL, &(spec[0])))
@@ -1934,14 +1940,14 @@ the maximum\nrepresentable value of type `long'"), optarg);
else
{
error (0, 0, _("warning: invalid width %lu; using %d instead"),
desired_width, l_c_m);
(unsigned long) desired_width, l_c_m);
bytes_per_block = l_c_m;
}
}
else
{
if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
bytes_per_block = l_c_m * (int) (DEFAULT_BYTES_PER_BLOCK / l_c_m);
bytes_per_block = l_c_m * (DEFAULT_BYTES_PER_BLOCK / l_c_m);
else
bytes_per_block = l_c_m;
}

View File

@@ -147,7 +147,10 @@ valid_format (const char *fmt)
fmt += strspn (fmt, "0123456789");
if (*fmt == '.')
fmt += strspn (++fmt, "0123456789");
{
++fmt;
fmt += strspn (fmt, "0123456789");
}
}
if (!(*fmt == 'e' || *fmt == 'f' || *fmt == 'g'))

View File

@@ -779,7 +779,7 @@ isaac_seed_finish (struct isaac_state *s)
#define ISAAC_SEED(s,x) isaac_seed_data (s, &(x), sizeof (x))
#if __GNUC__ >= 2 && (__i386__ || __alpha__ || _ARCH_PPC)
#if __GNUC__ >= 2 && (__i386__ || __alpha__)
/*
* Many processors have very-high-resolution timer registers,
* The timer registers can be made inaccessible, so we have to deal with the
@@ -815,6 +815,8 @@ isaac_seed_machdep (struct isaac_state *s)
__asm__ __volatile__ ("rpcc %0" : "=r" (t));
# endif
# if _ARCH_PPC
/* Code not used because this instruction is available only on first-
generation PPCs and evokes a SIGBUS on some Linux 2.4 kernels. */
word32 t;
__asm__ __volatile__ ("mfspr %0,22" : "=r" (t));
# endif
@@ -833,12 +835,12 @@ isaac_seed_machdep (struct isaac_state *s)
}
}
#else /* !(__i386__ || __alpha__ || _ARCH_PPC) */
#else /* !(__i386__ || __alpha__) */
/* Do-nothing stub */
# define isaac_seed_machdep(s) (void) 0
#endif /* !(__i386__ || __alpha__ || _ARCH_PPC) */
#endif /* !(__i386__ || __alpha__) */
/*

View File

@@ -32,8 +32,11 @@
#include "long-options.h"
#include "error.h"
#include "hard-locale.h"
#include "human.h"
#include "memcoll.h"
#include "physmem.h"
#include "xalloc.h"
#include "xstrtol.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "sort"
@@ -55,6 +58,7 @@ double strtod ();
#endif
/* Undefine, to avoid warning about redefinition on some systems. */
/* FIXME: Remove these: use MIN/MAX from sys2.h. */
#undef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#undef max
@@ -99,6 +103,8 @@ static int hard_LC_TIME;
#endif
#define NONZERO(x) (x != 0)
/* The kind of blanks for '-b' to skip in various options. */
enum blanktype { bl_start, bl_end, bl_both };
@@ -109,7 +115,7 @@ int eolchar = '\n';
struct line
{
char *text; /* Text of the line. */
int length; /* Length including final newline. */
size_t length; /* Length including final newline. */
char *keybeg; /* Start of first key. */
char *keylim; /* Limit of first key. */
};
@@ -118,29 +124,29 @@ struct line
struct lines
{
struct line *lines; /* Dynamically allocated array of lines. */
int used; /* Number of slots used. */
int alloc; /* Number of slots allocated. */
int limit; /* Max number of slots to allocate. */
size_t used; /* Number of slots used. */
size_t alloc; /* Number of slots allocated. */
size_t limit; /* Max number of slots to allocate. */
};
/* Input buffers. */
struct buffer
{
char *buf; /* Dynamically allocated buffer. */
int used; /* Number of bytes used. */
int alloc; /* Number of bytes allocated. */
int left; /* Number of bytes left from previous reads. */
int newline_free; /* Number of left bytes that are known
size_t used; /* Number of bytes used. */
size_t alloc; /* Number of bytes allocated. */
size_t left; /* Number of bytes left from previous reads. */
size_t newline_free; /* Number of left bytes that are known
to be newline-free. */
};
struct keyfield
{
int sword; /* Zero-origin 'word' to start at. */
int schar; /* Additional characters to skip. */
size_t sword; /* Zero-origin 'word' to start at. */
size_t schar; /* Additional characters to skip. */
int skipsblanks; /* Skip leading white space at start. */
int eword; /* Zero-origin first word after field. */
int echar; /* Additional characters in field. */
size_t eword; /* Zero-origin first word after field. */
size_t echar; /* Additional characters in field. */
int skipeblanks; /* Skip trailing white space at finish. */
int *ignore; /* Boolean array of characters to ignore. */
char *translate; /* Translation applied to characters. */
@@ -211,20 +217,18 @@ static MONTHTAB_CONST struct month monthtab[] =
/* During the merge phase, the number of files to merge at once. */
#define NMERGE 16
/* Initial buffer size for in-core sorting. The buffer will grow only
if a line longer than this is seen. */
#define SORTALLOC (8 * 1024 * 1024)
static int const sortalloc = SORTALLOC;
/* Minimum text buffer size. */
#define SORTALLOC_MIN (4 * NMERGE * sizeof (struct line))
/* Initial buffer size for in core merge buffers. Bear in mind that
up to NMERGE * mergealloc bytes may be allocated for merge buffers. */
static int const mergealloc = SORTALLOC / NMERGE / 2;
/* Minimum text buffer size if the user does not specify a size. */
#define SORTALLOC_DEFAULT_MIN max (SORTALLOC_MIN, 1024 * 1024)
/* Initial text buffer size for main-memory sorting. The buffer will
grow only if a line longer than this is seen. */
static size_t sortalloc;
/* Guess of average line length. */
static int const linelength = 30;
/* Maximum number of elements for the array(s) of struct line's, in bytes. */
#define LINEALLOC (SORTALLOC / 2)
static size_t const linelength = 30;
/* Array of directory names in which any temporary files are to be created. */
static char const **temp_dirs;
@@ -294,6 +298,7 @@ Write sorted concatenation of all FILE(s) to standard output.\n\
-o FILE write result on FILE instead of standard output\n\
-r reverse the result of comparisons\n\
-s stabilize sort by disabling last resort comparison\n\
-S SIZE use SIZE for main memory sorting\n\
-t SEP use SEParator instead of non- to whitespace transition\n\
-T DIRECTORY use DIRECTORY for temporary files, not $TMPDIR or %s\n\
multiple -T options specify multiple directories\n\
@@ -310,7 +315,12 @@ POS is F[.C][OPTS], where F is the field number and C the character position\n\
in the field, both counted from one with -k, from zero with the obsolescent\n\
form. OPTS is made up of one or more of Mbdfinr; this effectively disables\n\
global -Mbdfinr settings for that key. If no key is given, use the entire\n\
line as the key. With no FILE, or when FILE is -, read standard input.\n\
line as the key.\n\
\n\
SIZE may be followed by the following multiplicative suffixes:\n\
%% 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\
@@ -554,10 +564,83 @@ inittables (void)
#endif /* NLS */
}
/* Specify the amount of main memory to use when sorting. */
static void
specify_sort_size (char const *s)
{
uintmax_t n;
char *suffix;
enum strtol_error e = xstrtoumax (s, &suffix, 10, &n, "EgGkmMPtTYZ");
/* The default unit is kB. */
if (e == LONGINT_OK && ISDIGIT (suffix[-1]))
{
if (n <= UINTMAX_MAX / 1024)
n *= 1024;
else
e = LONGINT_OVERFLOW;
}
/* A 'b' suffix means bytes; a '%' suffix means percent of memory. */
if (e == LONGINT_INVALID_SUFFIX_CHAR && ISDIGIT (suffix[-1]) && ! suffix[1])
switch (suffix[0])
{
case 'b':
e = LONGINT_OK;
break;
case '%':
{
double mem = physmem_total () * n / 100;
/* Use "<", not "<=", to avoid problems with rounding. */
if (mem < UINTMAX_MAX)
{
n = mem;
e = LONGINT_OK;
}
else
e = LONGINT_OVERFLOW;
}
break;
}
if (e == LONGINT_OK)
{
/* Normally a buffer is allocated with sortalloc bytes, and a
line table with at most sortalloc / 2 bytes. So adjust the
size so that size * 1.5 is about n. */
sortalloc = (n / 3) * 2;
if (sortalloc == (n / 3) * 2)
{
if (sortalloc < SORTALLOC_MIN)
sortalloc = SORTALLOC_MIN;
return;
}
e = LONGINT_OVERFLOW;
}
STRTOL_FATAL_ERROR (s, _("sort size"), e);
}
/* Set the sort size to the default. */
static void
default_sort_size (void)
{
/* Set sortalloc to 50% of available memory, unless it overflows. */
double mem = physmem_available ();
sortalloc = min (mem, SIZE_MAX);
sortalloc >>= 1;
if (sortalloc < SORTALLOC_DEFAULT_MIN)
sortalloc = SORTALLOC_DEFAULT_MIN;
}
/* Initialize BUF, allocating ALLOC bytes initially. */
static void
initbuf (struct buffer *buf, int alloc)
initbuf (struct buffer *buf, size_t alloc)
{
buf->alloc = alloc;
buf->buf = xmalloc (buf->alloc);
@@ -569,7 +652,7 @@ initbuf (struct buffer *buf, int alloc)
file wasn't terminated by a newline, supply one. Return a count
of bytes buffered. */
static int
static size_t
fillbuf (struct buffer *buf, FILE *fp)
{
if (buf->used != buf->left)
@@ -580,10 +663,12 @@ fillbuf (struct buffer *buf, FILE *fp)
while (!feof (fp))
{
int cc;
size_t cc;
if (buf->used == buf->alloc)
{
buf->alloc *= 2;
if (buf->alloc < buf->used)
xalloc_die ();
buf->buf = xrealloc (buf->buf, buf->alloc);
}
cc = fread (buf->buf + buf->used, 1, buf->alloc - buf->used, fp);
@@ -608,6 +693,8 @@ fillbuf (struct buffer *buf, FILE *fp)
if (buf->newline_free != buf->used)
return buf->used;
buf->alloc *= 2;
if (buf->alloc < buf->used)
xalloc_die ();
buf->buf = xrealloc (buf->buf, buf->alloc);
}
buf->buf[buf->used++] = eolchar;
@@ -621,9 +708,13 @@ fillbuf (struct buffer *buf, FILE *fp)
for, ever. */
static void
initlines (struct lines *lines, int alloc, int limit)
initlines (struct lines *lines, size_t alloc, size_t limit)
{
if (limit < alloc)
alloc = limit;
lines->alloc = alloc;
if (SIZE_MAX / sizeof (struct line) < alloc)
xalloc_die ();
lines->lines = (struct line *) xmalloc (lines->alloc * sizeof (struct line));
lines->used = 0;
lines->limit = limit;
@@ -636,7 +727,8 @@ static char *
begfield (const struct line *line, const struct keyfield *key)
{
register char *ptr = line->text, *lim = ptr + line->length - 1;
register int sword = key->sword, schar = key->schar;
register size_t sword = key->sword;
register size_t schar = key->schar;
if (tab)
while (ptr < lim && sword--)
@@ -659,7 +751,7 @@ begfield (const struct line *line, const struct keyfield *key)
while (ptr < lim && blanks[UCHAR (*ptr)])
++ptr;
if (ptr + schar <= lim)
if (schar < lim - ptr)
ptr += schar;
else
ptr = lim;
@@ -674,7 +766,7 @@ static char *
limfield (const struct line *line, const struct keyfield *key)
{
register char *ptr = line->text, *lim = ptr + line->length - 1;
register int eword = key->eword, echar = key->echar;
register size_t eword = key->eword, echar = key->echar;
/* Note: from the POSIX spec:
The leading field separator itself is included in
@@ -692,7 +784,7 @@ limfield (const struct line *line, const struct keyfield *key)
{
while (ptr < lim && *ptr != tab)
++ptr;
if (ptr < lim && (eword || echar > 0))
if (ptr < lim && (eword | echar))
++ptr;
}
else
@@ -761,7 +853,7 @@ limfield (const struct line *line, const struct keyfield *key)
++ptr;
/* Advance PTR by ECHAR (if possible), but no further than LIM. */
if (ptr + echar <= lim)
if (echar < lim - ptr)
ptr += echar;
else
ptr = lim;
@@ -795,7 +887,9 @@ findlines (struct buffer *buf, struct lines *lines)
if (lines->used == lines->alloc)
{
lines->alloc *= 2;
lines->alloc = min (2 * lines->alloc, lines->limit);
if (SIZE_MAX / sizeof (struct line) < lines->alloc)
xalloc_die ();
lines->lines = (struct line *)
xrealloc ((char *) lines->lines,
lines->alloc * sizeof (struct line));
@@ -808,9 +902,9 @@ findlines (struct buffer *buf, struct lines *lines)
if (key)
{
/* Precompute the position of the first key for efficiency. */
line->keylim = 0 <= key->eword ? limfield (line, key) : ptr;
line->keylim = (key->eword == -1 ? ptr : limfield (line, key));
if (key->sword >= 0)
if (key->sword != -1)
line->keybeg = begfield (line, key);
else
{
@@ -902,7 +996,8 @@ fraccompare (register const char *a, register const char *b)
static int
numcompare (register const char *a, register const char *b)
{
register int tmpa, tmpb, loga, logb, tmp;
register int tmpa, tmpb, tmp;
register size_t loga, logb;
tmpa = *a;
tmpb = *b;
@@ -965,8 +1060,8 @@ numcompare (register const char *a, register const char *b)
tmpb = *++b;
while (IS_THOUSANDS_SEP (tmpb));
if (logb - loga != 0)
return logb - loga;
if (loga != logb)
return loga < logb ? 1 : -1;
if (!loga)
return 0;
@@ -1027,8 +1122,8 @@ numcompare (register const char *a, register const char *b)
tmpb = *++b;
while (IS_THOUSANDS_SEP (tmpb));
if (loga - logb != 0)
return loga - logb;
if (loga != logb)
return loga < logb ? -1 : 1;
if (!loga)
return 0;
@@ -1070,10 +1165,11 @@ general_numcompare (const char *sa, const char *sb)
Return 0 if the name in S is not recognized. */
static int
getmonth (const char *s, int len)
getmonth (const char *s, size_t len)
{
char *month;
register int i, lo = 0, hi = MONTHS_PER_YEAR, result;
register size_t i;
register int lo = 0, hi = MONTHS_PER_YEAR, result;
while (len > 0 && blanks[UCHAR (*s)])
{
@@ -1123,7 +1219,8 @@ keycompare (const struct line *a, const struct line *b)
register char *lima = a->keylim;
register char *limb = b->keylim;
int diff, lena, lenb;
int diff;
size_t lena, lenb;
for (;;)
{
@@ -1131,11 +1228,8 @@ keycompare (const struct line *a, const struct line *b)
register int *ignore = key->ignore;
/* Find the lengths. */
lena = lima - texta, lenb = limb - textb;
if (lena < 0)
lena = 0;
if (lenb < 0)
lenb = 0;
lena = lima <= texta ? 0 : lima - texta;
lenb = limb <= textb ? 0 : limb - textb;
if (key->skipeblanks)
{
@@ -1168,7 +1262,7 @@ keycompare (const struct line *a, const struct line *b)
{
char *copy_a = (char *) alloca (lena + 1 + lenb + 1);
char *copy_b = copy_a + lena + 1;
int new_len_a, new_len_b, i;
size_t new_len_a, new_len_b, i;
/* Ignore and/or translate chars before comparing. */
for (new_len_a = new_len_b = i = 0; i < max (lena, lenb); i++)
@@ -1194,7 +1288,7 @@ keycompare (const struct line *a, const struct line *b)
diff = memcoll (copy_a, new_len_a, copy_b, new_len_b);
}
else if (lena == 0)
diff = -lenb;
diff = - NONZERO (lenb);
else if (lenb == 0)
goto greater;
else
@@ -1232,7 +1326,7 @@ keycompare (const struct line *a, const struct line *b)
CMP_WITH_IGNORE (UCHAR (*texta), UCHAR (*textb));
}
else if (lena == 0)
diff = -lenb;
diff = - NONZERO (lenb);
else if (lenb == 0)
goto greater;
else
@@ -1253,7 +1347,7 @@ keycompare (const struct line *a, const struct line *b)
if (diff)
goto not_equal;
}
diff = lena - lenb;
diff = lena < lenb ? -1 : lena != lenb;
}
if (diff)
@@ -1264,12 +1358,12 @@ keycompare (const struct line *a, const struct line *b)
break;
/* Find the beginning and limit of the next field. */
if (key->eword >= 0)
if (key->eword != -1)
lima = limfield (a, key), limb = limfield (b, key);
else
lima = a->text + a->length - 1, limb = b->text + b->length - 1;
if (key->sword >= 0)
if (key->sword != -1)
texta = begfield (a, key), textb = begfield (b, key);
else
{
@@ -1298,7 +1392,8 @@ keycompare (const struct line *a, const struct line *b)
static int
compare (register const struct line *a, register const struct line *b)
{
int diff, alen, blen;
int diff;
size_t alen, blen;
/* First try to compare on the specified keys (if any).
The only two cases with no key at all are unadorned sort,
@@ -1316,23 +1411,23 @@ compare (register const struct line *a, register const struct line *b)
alen = a->length - 1, blen = b->length - 1;
if (alen == 0)
diff = - blen;
diff = - NONZERO (blen);
else if (blen == 0)
diff = alen;
diff = NONZERO (alen);
#ifdef ENABLE_NLS
else if (hard_LC_COLLATE)
diff = memcoll (a->text, alen, b->text, blen);
#endif
else if (! (diff = memcmp (a->text, b->text, min (alen, blen))))
diff = alen - blen;
diff = alen < blen ? -1 : alen != blen;
return reverse ? -diff : diff;
}
/* Check that the lines read from the given FP come in order. Print a
diagnostic (FILE_NAME, line number, contents of line) to stderr and return
the line number of the first out-of-order line (counting from 1) if they
are not in order. Otherwise, print no diagnostic and return zero. */
one if they are not in order. Otherwise, print no diagnostic
and return zero. */
static int
checkfp (FILE *fp, const char *file_name)
@@ -1340,16 +1435,17 @@ checkfp (FILE *fp, const char *file_name)
struct buffer buf; /* Input buffer. */
struct lines lines; /* Lines scanned from the buffer. */
struct line temp; /* Copy of previous line. */
int cc; /* Character count. */
int alloc;
int line_number = 1;
size_t cc; /* Character count. */
size_t alloc;
uintmax_t line_number = 1;
struct line *disorder_line IF_LINT (= NULL);
int disorder_line_number = 0;
uintmax_t disorder_line_number = 0;
struct keyfield *key = keylist;
size_t mergealloc = sortalloc / (2 * NMERGE);
initbuf (&buf, mergealloc);
initlines (&lines, mergealloc / linelength + 1,
LINEALLOC / ((NMERGE + NMERGE) * sizeof (struct line)));
sortalloc / (4 * NMERGE * sizeof (struct line)));
alloc = linelength;
temp.text = xmalloc (alloc);
@@ -1363,16 +1459,16 @@ checkfp (FILE *fp, const char *file_name)
{
struct line *prev_line; /* Pointer to previous line. */
int cmp; /* Result of calling compare. */
int i;
size_t i;
/* Compare each line in the buffer with its successor. */
for (i = 0; i < lines.used - 1; ++i)
for (i = 1; i < lines.used; ++i)
{
cmp = compare (&lines.lines[i], &lines.lines[i + 1]);
cmp = compare (&lines.lines[i - 1], &lines.lines[i]);
if ((unique && cmp >= 0) || (cmp > 0))
{
disorder_line = &lines.lines[i + 1];
disorder_line_number = line_number + i + 1;
disorder_line = &lines.lines[i];
disorder_line_number = line_number + i;
goto finish;
}
}
@@ -1383,8 +1479,14 @@ checkfp (FILE *fp, const char *file_name)
prev_line = lines.lines + (lines.used - 1);
if (alloc < prev_line->length)
{
while ((alloc *= 2) < prev_line->length)
continue;
do
{
if (alloc * 2 < alloc)
xalloc_die ();
alloc *= 2;
}
while (alloc < prev_line->length);
temp.text = xrealloc (temp.text, alloc);
}
memcpy (temp.text, prev_line->text, prev_line->length);
@@ -1416,8 +1518,9 @@ finish:
if (disorder_line_number)
{
fprintf (stderr, _("%s: %s:%d: disorder: "), program_name, file_name,
disorder_line_number);
char hr_buf[LONGEST_HUMAN_READABLE + 1];
fprintf (stderr, _("%s: %s:%s: disorder: "), program_name, file_name,
human_readable (disorder_line_number, hr_buf, 1, 1));
write_bytes (disorder_line->text, disorder_line->length, stderr,
_("standard error"));
}
@@ -1425,7 +1528,7 @@ finish:
free (buf.buf);
free ((char *) lines.lines);
free (temp.text);
return disorder_line_number;
return NONZERO (disorder_line_number);
}
/* Merge lines from FPS onto OFP. NFPS cannot be greater than NMERGE.
@@ -1439,8 +1542,9 @@ mergefps (FILE **fps, register int nfps, FILE *ofp, const char *output_file)
struct line saved; /* Saved line storage for unique check. */
struct line const *savedline IF_LINT (= NULL);
/* &saved if there is a saved line. */
int savealloc IF_LINT (= 0); /* Size allocated for the saved line. */
int cur[NMERGE]; /* Current line in each line table. */
size_t mergealloc = sortalloc / (2 * NMERGE);
size_t savealloc IF_LINT (= 0); /* Size allocated for the saved line. */
size_t cur[NMERGE]; /* Current line in each line table. */
int ord[NMERGE]; /* Table representing a permutation of fps,
such that lines[ord[0]].lines[cur[ord[0]]]
is the smallest line and will be next
@@ -1473,7 +1577,7 @@ mergefps (FILE **fps, register int nfps, FILE *ofp, const char *output_file)
else
{
initlines (&lines[i], mergealloc / linelength + 1,
LINEALLOC / ((NMERGE + NMERGE) * sizeof (struct line)));
sortalloc / (4 * NMERGE * sizeof (struct line)));
findlines (&buffer[i], &lines[i]);
cur[i] = 0;
}
@@ -1585,10 +1689,10 @@ mergefps (FILE **fps, register int nfps, FILE *ofp, const char *output_file)
/* Sort the array LINES with NLINES members, using TEMP for temporary space. */
static void
sortlines (struct line *lines, int nlines, struct line *temp)
sortlines (struct line *lines, size_t nlines, struct line *temp)
{
register struct line *lo, *hi, *t;
register int nlo, nhi;
register size_t nlo, nhi;
if (nlines == 2)
{
@@ -1638,10 +1742,7 @@ check (char **files, int nfiles)
for (i = 0; i < nfiles; ++i)
{
fp = xfopen (files[i], "r");
if (checkfp (fp, files[i]))
{
++disorders;
}
disorders += checkfp (fp, files[i]);
}
return disorders;
}
@@ -1694,8 +1795,8 @@ sort (char **files, int nfiles, FILE *ofp, const char *output_file)
{
struct buffer buf;
struct lines lines;
struct line *tmp;
int i, ntmp;
struct line *tmp = NULL;
size_t ntmp = 0;
FILE *fp, *tfp;
struct tempnode *node;
int n_temp_files = 0;
@@ -1703,9 +1804,7 @@ sort (char **files, int nfiles, FILE *ofp, const char *output_file)
initbuf (&buf, sortalloc);
initlines (&lines, sortalloc / linelength + 1,
LINEALLOC / sizeof (struct line));
ntmp = lines.alloc;
tmp = (struct line *) xmalloc (ntmp * sizeof (struct line));
sortalloc / (2 * sizeof (struct line)));
while (nfiles--)
{
@@ -1714,6 +1813,8 @@ sort (char **files, int nfiles, FILE *ofp, const char *output_file)
fp = xfopen (*files++, "r");
while (fillbuf (&buf, fp))
{
size_t i;
if (nfiles && buf.used != buf.alloc && feof (fp))
{
/* End of file, but there is more input and buffer room.
@@ -1726,8 +1827,13 @@ sort (char **files, int nfiles, FILE *ofp, const char *output_file)
findlines (&buf, &lines);
if (ntmp < lines.used)
{
while ((ntmp *= 2) < lines.used)
continue;
if (ntmp == 0)
ntmp = lines.used;
else
while ((ntmp *= 2) < lines.used)
continue;
if (SIZE_MAX / sizeof (struct line) < ntmp)
xalloc_die ();
tmp = (struct line *)
xrealloc ((char *) tmp, ntmp * sizeof (struct line));
}
@@ -1759,8 +1865,8 @@ sort (char **files, int nfiles, FILE *ofp, const char *output_file)
if (n_temp_files)
{
int i = n_temp_files;
tempfiles = (char **) xmalloc (n_temp_files * sizeof (char *));
i = n_temp_files;
for (node = temphead.next; i > 0; node = node->next)
tempfiles[--i] = node->name;
merge (tempfiles, n_temp_files, ofp, output_file);
@@ -1787,6 +1893,39 @@ badfieldspec (const char *s)
error (SORT_FAILURE, 0, _("invalid field specification `%s'"), s);
}
/* Parse the leading integer in STRING and store the resulting value
(which must fit into size_t) into *VAL. Return the address of the
suffix after the integer. */
static char const *
parse_field_count (char const *string, size_t *val)
{
/* '@' can't possibly be a valid suffix; return &bad_suffix so that
the caller will eventually invoke badfieldspec. */
static char const invalid_suffix = '@';
char *suffix;
uintmax_t n;
switch (xstrtoumax (string, &suffix, 10, &n, ""))
{
case LONGINT_OK:
case LONGINT_INVALID_SUFFIX_CHAR:
*val = n;
if (*val == n)
break;
/* Fall through. */
case LONGINT_OVERFLOW:
error (0, 0, _("count `%.*s' too large"),
(int) (suffix - string), string);
return &invalid_suffix;
case LONGINT_INVALID:
error (0, 0, _("invalid count at start of `%s'"), string);
return &invalid_suffix;
}
return suffix;
}
/* Handle interrupts and hangups. */
static void
@@ -1865,10 +2004,11 @@ int
main (int argc, char **argv)
{
struct keyfield *key = NULL, gkey;
char *s;
int i, t, t2;
char const *s;
int i;
int checkonly = 0, mergeonly = 0, nfiles = 0;
char *minus = "-", *outfile = minus, **files, *tmp;
char *minus = "-", **files, *tmp;
char const *outfile = minus;
FILE *ofp;
#ifdef SA_NOCLDSTOP
struct sigaction oldact, newact;
@@ -1966,18 +2106,10 @@ main (int argc, char **argv)
s = argv[i] + 1;
if (! (ISDIGIT (*s) || (*s == '.' && ISDIGIT (s[1]))))
badfieldspec (argv[i]);
for (t = 0; ISDIGIT (*s); ++s)
t = 10 * t + *s - '0';
t2 = 0;
s = parse_field_count (s, &key->sword);
if (*s == '.')
for (++s; ISDIGIT (*s); ++s)
t2 = 10 * t2 + *s - '0';
if (t2 || t)
{
key->sword = t;
key->schar = t2;
}
else
s = parse_field_count (s + 1, &key->schar);
if (! (key->sword | key->schar))
key->sword = -1;
s = set_ordering (s, key, bl_start);
if (*s)
@@ -1995,14 +2127,9 @@ main (int argc, char **argv)
key specifiers,\nthe +POS specifier must come first"));
usage (SORT_FAILURE);
}
for (t = 0; ISDIGIT (*s); ++s)
t = t * 10 + *s - '0';
t2 = 0;
s = parse_field_count (s, &key->eword);
if (*s == '.')
for (++s; ISDIGIT (*s); ++s)
t2 = t2 * 10 + *s - '0';
key->eword = t;
key->echar = t2;
s = parse_field_count (s + 1, &key->echar);
s = set_ordering (s, key, bl_end);
if (*s)
badfieldspec (argv[i]);
@@ -2039,17 +2166,14 @@ key specifiers,\nthe +POS specifier must come first"));
/* Get POS1. */
if (!ISDIGIT (*s))
badfieldspec (argv[i]);
for (t = 0; ISDIGIT (*s); ++s)
t = 10 * t + *s - '0';
if (t == 0)
s = parse_field_count (s, &key->sword);
if (! key->sword--)
{
/* Provoke with `sort -k0' */
error (0, 0, _("the starting field number argument \
to the `-k' option must be positive"));
badfieldspec (argv[i]);
}
--t;
t2 = 0;
if (*s == '.')
{
if (!ISDIGIT (s[1]))
@@ -2059,23 +2183,16 @@ to the `-k' option must be positive"));
lacks following character offset"));
badfieldspec (argv[i]);
}
for (++s; ISDIGIT (*s); ++s)
t2 = 10 * t2 + *s - '0';
if (t2 == 0)
s = parse_field_count (s + 1, &key->schar);
if (! key->schar--)
{
/* Provoke with `sort -k1.0' */
error (0, 0, _("starting field character offset \
argument to the `-k' option\nmust be positive"));
badfieldspec (argv[i]);
}
--t2;
}
if (t2 || t)
{
key->sword = t;
key->schar = t2;
}
else
if (! (key->sword | key->schar))
key->sword = -1;
s = set_ordering (s, key, bl_start);
if (*s == 0)
@@ -2097,17 +2214,14 @@ lacks following field spec"));
badfieldspec (argv[i]);
}
/* Get POS2. */
for (t = 0; ISDIGIT (*s); ++s)
t = t * 10 + *s - '0';
if (t == 0)
s = parse_field_count (s, &key->eword);
if (! key->eword--)
{
/* Provoke with `sort -k1,0' */
error (0, 0, _("ending field number argument \
to the `-k' option must be positive"));
badfieldspec (argv[i]);
}
--t;
t2 = 0;
if (*s == '.')
{
if (!ISDIGIT (s[1]))
@@ -2117,16 +2231,13 @@ to the `-k' option must be positive"));
but lacks following character offset"));
badfieldspec (argv[i]);
}
for (++s; ISDIGIT (*s); ++s)
t2 = t2 * 10 + *s - '0';
s = parse_field_count (s + 1, &key->echar);
}
else
{
/* `-k 2,3' is equivalent to `+1 -3'. */
++t;
key->eword++;
}
key->eword = t;
key->echar = t2;
s = set_ordering (s, key, bl_end);
if (*s)
badfieldspec (argv[i]);
@@ -2153,6 +2264,15 @@ but lacks following character offset"));
case 's':
stable = 1;
break;
case 'S':
if (s[1])
specify_sort_size (++s);
else if (i < argc - 1)
specify_sort_size (argv[++i]);
else
error (SORT_FAILURE, 0,
_("option `-S' requires an argument"));
goto outer;
case 't':
if (s[1])
tab = *++s;
@@ -2211,7 +2331,7 @@ but lacks following character offset"));
for (key = keylist; key; key = key->next)
if (!key->ignore && !key->translate && !key->skipsblanks && !key->reverse
&& !key->skipeblanks && !key->month && !key->numeric
&& !key->general_numeric)
&& !key->general_numeric)
{
key->ignore = gkey.ignore;
key->translate = gkey.translate;
@@ -2241,6 +2361,9 @@ but lacks following character offset"));
files = &minus;
}
if (sortalloc == 0)
default_sort_size ();
if (checkonly)
{
if (nfiles > 1)

View File

@@ -167,6 +167,14 @@ char *alloca ();
# include <sys/exceptn.h>
#endif
#if HAVE_STDINT_H
# include <stdint.h>
#endif
#if HAVE_INTTYPES_H
# include <inttypes.h> /* for the definition of UINTMAX_MAX */
#endif
#include <ctype.h>
/* Jim Meyering writes:
@@ -519,6 +527,22 @@ enum
# define ULONG_MAX TYPE_MAXIMUM (unsigned long)
#endif
#ifndef SIZE_MAX
# define SIZE_MAX TYPE_MAXIMUM (size_t)
#endif
#ifndef UINTMAX_MAX
# define UINTMAX_MAX TYPE_MAXIMUM (uintmax_t)
#endif
#ifndef OFF_T_MIN
# define OFF_T_MIN TYPE_MINIMUM (off_t)
#endif
#ifndef OFF_T_MAX
# define OFF_T_MAX TYPE_MAXIMUM (off_t)
#endif
#ifndef UID_T_MAX
# define UID_T_MAX TYPE_MAXIMUM (uid_t)
#endif
@@ -531,6 +555,10 @@ enum
# define PID_T_MAX TYPE_MAXIMUM (pid_t)
#endif
#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif
/* Use this to suppress gcc's `...may be used before initialized' warnings. */
#ifdef lint
# define IF_LINT(Code) Code

View File

@@ -44,14 +44,6 @@
#define AUTHORS \
"Paul Rubin, David MacKenzie, Ian Lance Taylor, and Jim Meyering"
#ifndef OFF_T_MIN
# define OFF_T_MIN TYPE_MINIMUM (off_t)
#endif
#ifndef OFF_T_MAX
# define OFF_T_MAX TYPE_MAXIMUM (off_t)
#endif
#ifndef ENOSYS
/* Some systems don't have ENOSYS -- this should be a big enough
value that no valid errno value will match it. */
@@ -1145,6 +1137,9 @@ tail_file (struct File_spec *f, off_t n_units)
{
f->fd = -1;
f->errnum = errno;
f->ignore = 0;
f->ino = 0;
f->dev = 0;
}
error (0, errno, "%s", pretty_name (f));
errors = 1;
@@ -1382,8 +1377,8 @@ parse_options (int argc, char **argv,
{
strtol_error s_err;
unsigned long int tmp_ulong;
s_err = xstrtoul (optarg, NULL, 10, &tmp_ulong, "bkm");
uintmax_t n;
s_err = xstrtoumax (optarg, NULL, 10, &n, "bkm");
if (s_err == LONGINT_INVALID)
{
error (EXIT_FAILURE, 0, "%s: %s", optarg,
@@ -1391,14 +1386,16 @@ parse_options (int argc, char **argv,
? _("invalid number of lines")
: _("invalid number of bytes")));
}
if (s_err != LONGINT_OK || tmp_ulong > OFF_T_MAX)
{
error (EXIT_FAILURE, 0,
_("%s: %s is so large that it is not representable"),
optarg,
c == 'n' ? _("number of lines") : _("number of bytes"));
}
*n_units = (off_t) tmp_ulong;
if (s_err != LONGINT_OK)
error (EXIT_FAILURE, 0,
_("%s: is so large that it is not representable"), optarg);
if (OFF_T_MAX < n)
error (EXIT_FAILURE, 0,
_("%s is larger than the maximum file size on this system"),
optarg);
*n_units = (off_t) n;
}
break;

7
tests/chgrp/Makefile.am Normal file
View File

@@ -0,0 +1,7 @@
## Process this file with automake to produce Makefile.in -*-Makefile-*-.
AUTOMAKE_OPTIONS = 1.4 gnits
TESTS = basic deref recurse
EXTRA_DIST = $(TESTS)
TESTS_ENVIRONMENT = \
PATH=`pwd`/../../src:$$PATH

283
tests/chgrp/Makefile.in Normal file
View File

@@ -0,0 +1,283 @@
# Makefile.in generated automatically by automake 1.4a from Makefile.am
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_FLAG =
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
@SET_MAKE@
host_alias = @host_alias@
host_triplet = @host@
AMDEP = @AMDEP@
AMTAR = @AMTAR@
AWK = @AWK@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
CXXCPP = @CXXCPP@
DATADIRNAME = @DATADIRNAME@
DEPDIR = @DEPDIR@
DF_PROG = @DF_PROG@
FESETROUND_LIBM = @FESETROUND_LIBM@
GENCAT = @GENCAT@
GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
GLIBC21 = @GLIBC21@
GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
GNU_PACKAGE = @GNU_PACKAGE@
GT_NO = @GT_NO@
GT_YES = @GT_YES@
INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
INSTOBJEXT = @INSTOBJEXT@
INTLDEPS = @INTLDEPS@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
KMEM_GROUP = @KMEM_GROUP@
LIBICONV = @LIBICONV@
LIBOBJS = @LIBOBJS@
LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
LIB_CRYPT = @LIB_CRYPT@
LIB_NANOSLEEP = @LIB_NANOSLEEP@
MAKEINFO = @MAKEINFO@
MAN = @MAN@
MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
NEED_SETGID = @NEED_SETGID@
OPTIONAL_BIN_PROGS = @OPTIONAL_BIN_PROGS@
OPTIONAL_BIN_ZCRIPTS = @OPTIONAL_BIN_ZCRIPTS@
PACKAGE = @PACKAGE@
PERL = @PERL@
POFILES = @POFILES@
POSUB = @POSUB@
POW_LIBM = @POW_LIBM@
RANLIB = @RANLIB@
SEQ_LIBM = @SEQ_LIBM@
SQRT_LIBM = @SQRT_LIBM@
U = @U@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
YACC = @YACC@
install_sh = @install_sh@
l = @l@
AUTOMAKE_OPTIONS = 1.4 gnits
TESTS = basic deref recurse
EXTRA_DIST = $(TESTS)
TESTS_ENVIRONMENT = \
PATH=`pwd`/../../src:$$PATH
subdir = tests/chgrp
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnits tests/chgrp/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
tags: TAGS
TAGS:
check-TESTS: $(TESTS)
@failed=0; all=0; xfail=0; xpass=0; \
srcdir=$(srcdir); export srcdir; \
list='$(TESTS)'; \
if test -n "$$list"; then \
for tst in $$list; do \
if test -f ./$$tst; then dir=./; \
elif test -f $$tst; then dir=; \
else dir="$(srcdir)/"; fi; \
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*" $$tst "*) \
xpass=`expr $$xpass + 1`; \
failed=`expr $$failed + 1`; \
echo "XPASS: $$tst"; \
;; \
*) \
echo "PASS: $$tst"; \
;; \
esac; \
elif test $$? -ne 77; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*" $$tst "*) \
xfail=`expr $$xfail + 1`; \
echo "XFAIL: $$tst"; \
;; \
*) \
failed=`expr $$failed + 1`; \
echo "FAIL: $$tst"; \
;; \
esac; \
fi; \
done; \
if test "$$failed" -eq 0; then \
if test "$$xfail" -eq 0; then \
banner="All $$all tests passed"; \
else \
banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
fi; \
else \
if test "$$xpass" -eq 0; then \
banner="$$failed of $$all tests failed"; \
else \
banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
fi; \
fi; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
echo "$$dashes"; \
test "$$failed" -eq 0; \
fi
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pR $$d/$$file $(distdir) \
|| exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
-rm -f Makefile.in
mostlyclean-am: mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-generic clean-am
distclean: distclean-am
maintainer-clean-am: maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: tags check-TESTS distdir info-am info dvi-am dvi check check-am \
installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all install-strip installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

89
tests/chgrp/basic Executable file
View File

@@ -0,0 +1,89 @@
#!/bin/sh
# make sure chgrp is reasonable
if test "$VERBOSE" = yes; then
set -x
chgrp --version
fi
. $srcdir/../envvar-check
. $srcdir/../lang-default
. $srcdir/../group-names
pwd=`pwd`
tmp=basic.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
framework_failure=0
mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework' 1>&2
(exit 1); exit
fi
fail=0
set _ $groups; shift
g1=$1
g2=$2
mkdir d
touch f f2 d/f3
chgrp $g1 f || fail=1
chgrp $g2 f || fail=1
chgrp $g2 f2 || fail=1
(
chgrp -c $g1 f
chgrp -c $g2 f
chgrp -c $g2 f
chgrp --verbose $g1 f
chgrp --verbose $g1 f
chgrp --verbose --reference=f2 f
chgrp -R --verbose $g2 d
chgrp -R --verbose $g1 d
chgrp -R -c $g2 d
chgrp -R -c $g1 d
chgrp -c $g2 d
rm -f f
touch f
ln -s f symlink
chgrp $g1 f
chgrp $g2 symlink 2> /dev/null
# This should not change the group of f.
chgrp -c $g2 symlink 2> /dev/null
chgrp -c $g2 f
# This *should* change the group of f.
# Though note that the diagnostic is misleading in that
# it says the `group of `symlink'' has been changed.
chgrp --dereference -c $g1 symlink
) 2>&1 | sed "s/ $g1$/ G1/;s/ $g2$/ G2/" > actual
cat <<\EOF > expected
changed group of `f' to G1
changed group of `f' to G2
changed group of `f' to G1
group of `f' retained as G1
changed group of `f' to G2
changed group of `d' to G2
changed group of `d/f3' to G2
changed group of `d' to G1
changed group of `d/f3' to G1
changed group of `d' to G2
changed group of `d/f3' to G2
changed group of `d' to G1
changed group of `d/f3' to G1
changed group of `d' to G2
changed group of `f' to G2
changed group of `symlink' to G1
EOF
cmp expected actual \
|| { diff -u expected actual 1>&2; fail=1; }
(exit $fail); exit

67
tests/chgrp/deref Executable file
View File

@@ -0,0 +1,67 @@
#!/bin/sh
# see if chgrp can change the group of a symlink
if test "$VERBOSE" = yes; then
set -x
chgrp --version
fi
. $srcdir/../group-names
pwd=`pwd`
tmp=slink.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
framework_failure=0
mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework' 1>&2
(exit 1); exit
fi
set _ $groups; shift
g1=$1
g2=$2
touch f
ln -s f symlink
chgrp $g2 symlink 2> /dev/null
set _ `ls -l symlink`
g=$5
test "$g" = $g2 || {
cat <<EOF 1>&2
$0: skipping this test; your system doesn't support changing
the owner or group of a symbolic link.
EOF
(exit 77); exit
}
fail=0
chgrp $g1 f
set _ `ls -l f`; g=$5; test "$g" = $g1 || fail=1
chgrp $g2 symlink || fail=1
set _ `ls -l f`; g=$5; test "$g" = $g1 || fail=1
set _ `ls -l symlink`; g=$5; test "$g" = $g2 || fail=1
# This should not change the group of f.
chgrp $g2 symlink || fail=1
set _ `ls -l f`; g=$5; test "$g" = $g1 || fail=1
set _ `ls -l symlink`; g=$5; test "$g" = $g2 || fail=1
chgrp $g2 f
set _ `ls -l f`; g=$5; test "$g" = $g2 || fail=1
# This *should* change the group of f.
# Though note that the diagnostic you'd get with -c is misleading in that
# it says the `group of `symlink'' has been changed.
chgrp --dereference $g1 symlink
set _ `ls -l f`; g=$5; test "$g" = $g1 || fail=1
set _ `ls -l symlink`; g=$5; test "$g" = $g2 || fail=1
(exit $fail); exit

47
tests/chgrp/recurse Executable file
View File

@@ -0,0 +1,47 @@
#!/bin/sh
# make sure chgrp handles --recursive w/symlinks
if test "$VERBOSE" = yes; then
set -x
chgrp --version
fi
. $srcdir/../group-names
pwd=`pwd`
tmp=slink.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
framework_failure=0
mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework' 1>&2
(exit 1); exit
fi
set _ $groups; shift
g1=$1
g2=$2
fail=0
# chgrp -R should not traverse a symlink to a directory.
mkdir d e
touch e/f
ln -s ../e d/s
chgrp -R $g1 e/f || fail=1
# Neither of the following should change the group of e/f
chgrp -R $g2 d
set _ `ls -l e/f`; g=$5; test "$g" = $g1 || fail=1
chgrp --deref -R $g2 d
set _ `ls -l e/f`; g=$5; test "$g" = $g1 || fail=1
# Even when the symlink-to-directory is a command line argument, it should
# not be traversed. So this shouldn't change the group of e/f either.
chgrp --deref -R $g2 d/s || fail=1
set _ `ls -l e/f`; g=$5; test "$g" = $g1 || fail=1
(exit $fail); exit

View File

@@ -9,4 +9,4 @@ TESTS_ENVIRONMENT = \
PATH=`pwd`/../../src:$$PATH \
PROG=dd
TESTS = misc not-rewound skip-seek
TESTS = misc not-rewound skip-seek skip-seek2

View File

@@ -126,7 +126,7 @@ TESTS_ENVIRONMENT = \
PROG=dd
TESTS = misc not-rewound skip-seek
TESTS = misc not-rewound skip-seek skip-seek2
subdir = tests/dd
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h

View File

@@ -34,14 +34,6 @@ my @Tests =
{ERR=> "3+0 records in\n3+0 records out\n"},
{CMP=> ['zy123utsrqponmlkji', {'@AUX@'=> undef}]},
],
[
'2', qw (bs=5 skip=1B seek=2B conv=notrunc count=1 of=@AUX@ < ),
{IN=> '0123456789abcdef'},
{AUX=> 'zyxwvutsrqponmlkji'},
{OUT=> ''},
{ERR=> "1+0 records in\n1+0 records out\n"},
{CMP=> ['zy12345srqponmlkji', {'@AUX@'=> undef}]},
],
[
'3', qw (bs=5 skip=1 seek=1 conv=notrunc count=1 of=@AUX@ < ),
{IN=> '0123456789abcdef'},

40
tests/dd/skip-seek2 Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/sh
# show how to skip an amount that is smaller than the nominal block size.
# There's a more realistic example in the documentation.
if test "$VERBOSE" = yes; then
set -x
dd --version
fi
pwd=`pwd`
tmp=skip-seek.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
framework_failure=0
mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework'
(exit 1); exit
fi
fail=0
echo LA:3456789abcdef > in || fail=1
(dd bs=1 skip=3 count=0 && dd bs=5) < in > out 2> /dev/null || fail=1
case `cat out` in
3456789abcdef) ;;
*) fail=1 ;;
esac
echo LA:3456789abcdef > in || fail=1
(dd bs=1 skip=3 count=0 && dd bs=5 count=2) < in > out 2> /dev/null || fail=1
case `cat out` in
3456789abc) ;;
*) fail=1 ;;
esac
(exit $fail); exit

19
tests/group-names Normal file
View File

@@ -0,0 +1,19 @@
# -*- sh -*-
# Set `groups' to a space-separated list of at least two groups of which
# the user is a member.
groups=${FETISH_GROUPS-`id -nG 2>/dev/null`}
case "$groups" in
*' '*) ;;
*) cat <<EOF 1>&2
$0: this test requires that you be a member of more than one group,
but running \`id -nG' either failed or found just one. If you really
are a member of at least two group, then rerun this test with FETISH_GROUPS
set in your environment to the space-separated list of names. E.g.,
env FETISH_GROUPS='users cdrom' make check
EOF
(exit 77); exit
;;
esac

View File

@@ -2,7 +2,7 @@
AUTOMAKE_OPTIONS = 1.2 gnits
TESTS = rt-1 time-1 symlink-slash
TESTS = rt-1 time-1 symlink-slash follow-slink
EXTRA_DIST = $(TESTS)
TESTS_ENVIRONMENT = \
top_srcdir=$(top_srcdir) \

View File

@@ -118,7 +118,7 @@ l = @l@
AUTOMAKE_OPTIONS = 1.2 gnits
TESTS = rt-1 time-1 symlink-slash
TESTS = rt-1 time-1 symlink-slash follow-slink
EXTRA_DIST = $(TESTS)
TESTS_ENVIRONMENT = \
top_srcdir=$(top_srcdir) \

28
tests/ls/follow-slink Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/sh
# make sure ls -L always follows symlinks
if test "$VERBOSE" = yes; then
set -x
ls --version
fi
pwd=`pwd`
tmp=follow-sl.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
framework_failure=0
mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
ln -s link link || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework'
(exit 1); exit
fi
fail=0
ls -L link 2> /dev/null && fail=1
(exit $fail); exit

View File

@@ -1,5 +1,6 @@
#!/bin/sh
# make sure --parents works with a trailing slash
# Ensure that mkdir works with arguments specified with and without
# a trailing slash.
if test "$VERBOSE" = yes; then
set -x
@@ -25,4 +26,8 @@ fail=0
mkdir -p dir/ || fail=1
test -d dir || fail=1
# This failed on NetBSD for fileutils-4.0.33.
mkdir d2/ || fail=1
test -d d2 || fail=1
(exit $fail); exit

View File

@@ -50,9 +50,9 @@ test -d $dir && fail=1
ls $other_partition_tmpdir/$null > /dev/null || fail=1
test -d $other_partition_tmpdir/$dir/a/b/c || fail=1
sed "s,$other_partition_tmpdir,XXX," out > out2
sed "s,$other_partition_tmpdir,XXX," out | sort > out2
cat > exp <<EOF
cat <<EOF | sort > exp
\`$null' -> \`XXX/$null'
removing \`$null'
\`$dir' -> \`XXX/$dir'

View File

@@ -6,6 +6,9 @@ if test "$VERBOSE" = yes; then
FIXME --version
fi
# FIXME: . $srcdir/../envvar-check
# FIXME: . $srcdir/../lang-default
pwd=`pwd`
tmp=FIXME.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
@@ -16,7 +19,7 @@ mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework'
echo 'failure in testing framework' 1>&2
(exit 1); exit
fi

View File

@@ -9,4 +9,4 @@ TESTS_ENVIRONMENT = \
PATH=`pwd`/../../src:$$PATH \
PROG=tail
TESTS = assert
TESTS = assert assert-2

View File

@@ -126,7 +126,7 @@ TESTS_ENVIRONMENT = \
PROG=tail
TESTS = assert
TESTS = assert assert-2
subdir = tests/tail-2
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h

46
tests/tail-2/assert-2 Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/sh
# This variant of `assert' would get a UMR reliably in 2.0.9.
# Due to a race condition in the test, the `assert' script would get
# the UMR on Solaris only some of the time, and not at all on Linux/GNU.
if test "$VERBOSE" = yes; then
set -x
tail --version
fi
tmp=tail-as2.$$
pwd=`pwd`
trap "cd $pwd; rm -rf $tmp" 0 1 2 3 15
test_failure=0
mkdir $tmp || test_failure=1
cd $tmp || test_failure=1
if test $test_failure = 1; then
echo 'failure in testing framework'
exit 1
fi
ok='ok ok ok'
touch a
tail --follow=name a foo > err 2>&1 &
tail_pid=$!
# Arrange for the tail process to die after 12 seconds.
(sleep 12; kill $tail_pid) &
echo $ok > f
echo sleeping for 7 seconds...
sleep 7
mv f foo
# echo waiting....
wait
case "`cat err`" in
*$ok) fail=0;;
*) fail=1;;
esac
test $fail = 1 && cat err
exit $fail