mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
Compare commits
223 Commits
FILEUTILS-
...
FILEUTILS-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c8f0df4f0 | ||
|
|
69e09f0559 | ||
|
|
1a18604b2e | ||
|
|
eae1c2b69c | ||
|
|
4c038111f8 | ||
|
|
a82d4c2b3d | ||
|
|
0cba2d7f5b | ||
|
|
a87ae161be | ||
|
|
275b1879c3 | ||
|
|
66cf2ad8ce | ||
|
|
0966c0f860 | ||
|
|
83a6c55c74 | ||
|
|
3c46adfe19 | ||
|
|
0787040b75 | ||
|
|
bf86c62a33 | ||
|
|
915dacbb85 | ||
|
|
b6b86da148 | ||
|
|
de38d76a18 | ||
|
|
166c00189a | ||
|
|
bca787f7c4 | ||
|
|
258f00968a | ||
|
|
bc40f9fcef | ||
|
|
d81418fd5e | ||
|
|
85ab4b9988 | ||
|
|
f75f8a4b1d | ||
|
|
dfada44550 | ||
|
|
5d4c822ef7 | ||
|
|
55f51356fb | ||
|
|
3f6afc4a7a | ||
|
|
dc87bf344c | ||
|
|
7a41a27413 | ||
|
|
8dc25234e0 | ||
|
|
24ad4ecf29 | ||
|
|
c9f0363bea | ||
|
|
c44bd5683d | ||
|
|
ae8bf0e8f1 | ||
|
|
fbba4d8d5e | ||
|
|
2b64713ac6 | ||
|
|
2464a2cd9d | ||
|
|
96e6715ebe | ||
|
|
72d973cb61 | ||
|
|
39d300f12b | ||
|
|
76f8538bf6 | ||
|
|
71411370e7 | ||
|
|
eb24d1f55c | ||
|
|
608b347584 | ||
|
|
6c4cbe6b5f | ||
|
|
ad31d9b60c | ||
|
|
8e2ee9a689 | ||
|
|
067af316b6 | ||
|
|
c0ab7dc021 | ||
|
|
8233adab59 | ||
|
|
be74434bbd | ||
|
|
bbc027cf8b | ||
|
|
43da73f064 | ||
|
|
ffc1ef87ea | ||
|
|
66e2135f07 | ||
|
|
e6a5c51ed7 | ||
|
|
d952853f74 | ||
|
|
3ebf224b28 | ||
|
|
9be2faa156 | ||
|
|
a8fff5ee1f | ||
|
|
4ab4534292 | ||
|
|
0e81b6b48e | ||
|
|
694c6b3a86 | ||
|
|
9724aab7a6 | ||
|
|
b6ca14a123 | ||
|
|
976f3796be | ||
|
|
1c643649b0 | ||
|
|
3337b5a092 | ||
|
|
b41ab84baa | ||
|
|
af996c06d0 | ||
|
|
2a21b4cf40 | ||
|
|
3614a52150 | ||
|
|
d2be99eb17 | ||
|
|
fca6110993 | ||
|
|
9bb0e5cdb7 | ||
|
|
cf302e3bc9 | ||
|
|
b50fed9980 | ||
|
|
baf047f89a | ||
|
|
a65f9eef4a | ||
|
|
9c149c3b6c | ||
|
|
d64368c699 | ||
|
|
97e76d3e24 | ||
|
|
a157495002 | ||
|
|
3c805daf45 | ||
|
|
8f55fdc385 | ||
|
|
26f88f15c8 | ||
|
|
6820c8729e | ||
|
|
78169b6a2f | ||
|
|
5a795ec749 | ||
|
|
d26ef4e978 | ||
|
|
40d911bc45 | ||
|
|
748db39d02 | ||
|
|
4db97b7a7d | ||
|
|
f8b26d3ade | ||
|
|
5c8eb8ec36 | ||
|
|
64f7bff756 | ||
|
|
040db4c3fe | ||
|
|
34ef74b11c | ||
|
|
de4a3dfb26 | ||
|
|
108881a3b2 | ||
|
|
7d5f893b7f | ||
|
|
8d977c3978 | ||
|
|
73f1bc31d7 | ||
|
|
497d1d9e97 | ||
|
|
764dd3149e | ||
|
|
b2b9bed164 | ||
|
|
9580e7cc87 | ||
|
|
a05267197a | ||
|
|
a90e5f5a69 | ||
|
|
1f47a082c4 | ||
|
|
7b55b7aa13 | ||
|
|
bcc94017bc | ||
|
|
b615d79ac3 | ||
|
|
04f549820f | ||
|
|
ded8b14afb | ||
|
|
4504b81f3b | ||
|
|
222412dbf1 | ||
|
|
71751f757d | ||
|
|
8c8424d0c2 | ||
|
|
e42f27d147 | ||
|
|
d1cca1ee9c | ||
|
|
0654f3206d | ||
|
|
67cf94a857 | ||
|
|
69ed54e544 | ||
|
|
3dabe6b533 | ||
|
|
2845214164 | ||
|
|
6b8102a180 | ||
|
|
570074d6d1 | ||
|
|
72a6d74ab2 | ||
|
|
cd6f0af0ea | ||
|
|
2746cd50c3 | ||
|
|
8a4261c7a5 | ||
|
|
90799b6c68 | ||
|
|
1c6320fe7c | ||
|
|
fecdd2bd2b | ||
|
|
15691fb64f | ||
|
|
cb366955f3 | ||
|
|
82a6fbda1c | ||
|
|
177b2553e2 | ||
|
|
814e63e371 | ||
|
|
2eed25f2ed | ||
|
|
1be9e19c7d | ||
|
|
b7895d0d10 | ||
|
|
8461820956 | ||
|
|
86960ce221 | ||
|
|
6670163eee | ||
|
|
437f8becaa | ||
|
|
5233121102 | ||
|
|
25c2989d30 | ||
|
|
4f96dfa43e | ||
|
|
f559a4afa3 | ||
|
|
b5d4b2c555 | ||
|
|
d8a157a00e | ||
|
|
85a75d3a16 | ||
|
|
d183ecddcd | ||
|
|
e30c09b4cb | ||
|
|
9d5d7f0d50 | ||
|
|
caae4ed5a7 | ||
|
|
a1ca60f4e5 | ||
|
|
ce861b2cb3 | ||
|
|
67ec78d188 | ||
|
|
d661be38ed | ||
|
|
69e30c7f2a | ||
|
|
8973e2b38c | ||
|
|
df52f23ebf | ||
|
|
5edc91fc05 | ||
|
|
8b4ac20908 | ||
|
|
1a0d9ea086 | ||
|
|
e49511faef | ||
|
|
e05c32a868 | ||
|
|
c2f898236f | ||
|
|
501ebc1cba | ||
|
|
77182607c0 | ||
|
|
6769657fa3 | ||
|
|
dab453378b | ||
|
|
aa266c29eb | ||
|
|
6b94589fa4 | ||
|
|
0d849addb3 | ||
|
|
1698b85090 | ||
|
|
a538ba0149 | ||
|
|
41f20fd38f | ||
|
|
1c8189de61 | ||
|
|
525e76fce0 | ||
|
|
d91624bd99 | ||
|
|
1c71127370 | ||
|
|
4f1553c89f | ||
|
|
1b9cb7ea23 | ||
|
|
479aba180c | ||
|
|
8eeae63a74 | ||
|
|
07584e33ec | ||
|
|
33ba435db5 | ||
|
|
73fe66c783 | ||
|
|
cc27b86c60 | ||
|
|
9db47bb808 | ||
|
|
8bf3961df0 | ||
|
|
df7d583cc2 | ||
|
|
271e41850b | ||
|
|
97b58344c5 | ||
|
|
627dac6c07 | ||
|
|
0742bc284e | ||
|
|
acca4638b8 | ||
|
|
05aabec021 | ||
|
|
e996c1bd77 | ||
|
|
b529a77be8 | ||
|
|
4faf0a9a17 | ||
|
|
3e50cea2f5 | ||
|
|
339738f351 | ||
|
|
a48a4d5c63 | ||
|
|
57a0382b5f | ||
|
|
835a8fa634 | ||
|
|
4ff7ab63ab | ||
|
|
d92f4ac85e | ||
|
|
21b8c52ae9 | ||
|
|
7303ca25db | ||
|
|
060fb58f86 | ||
|
|
d185a442b9 | ||
|
|
86046cb32f | ||
|
|
1500316caf | ||
|
|
72454050bb | ||
|
|
b0b9c6fee7 | ||
|
|
4a9feba665 |
@@ -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
2
THANKS
@@ -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
|
||||
|
||||
182
doc/texinfo.tex
182
doc/texinfo.tex
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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
58
lib/physmem.c
Normal 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
19
lib/physmem.h
Normal 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_ */
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
32
m4/ChangeLog
32
m4/ChangeLog
@@ -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.
|
||||
|
||||
@@ -11,6 +11,7 @@ chown.m4 \
|
||||
codeset.m4 \
|
||||
d-ino.m4 \
|
||||
d-type.m4 \
|
||||
dos.m4 \
|
||||
error.m4 \
|
||||
fnmatch.m4 \
|
||||
fpending.m4 \
|
||||
|
||||
@@ -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
27
m4/dos.m4
Normal 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.])
|
||||
])
|
||||
@@ -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])
|
||||
|
||||
@@ -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])
|
||||
|
||||
])
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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]
|
||||
|
||||
247
src/chgrp.c
247
src/chgrp.c
@@ -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
366
src/chown-core.c
Normal 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
89
src/chown-core.h
Normal 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 */
|
||||
256
src/chown.c
256
src/chown.c
@@ -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);
|
||||
}
|
||||
|
||||
68
src/dd.c
68
src/dd.c
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
29
src/id.c
29
src/id.c
@@ -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);
|
||||
|
||||
26
src/ls.c
26
src/ls.c
@@ -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))
|
||||
{
|
||||
|
||||
18
src/mkdir.c
18
src/mkdir.c
@@ -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
310
src/od.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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'))
|
||||
|
||||
@@ -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__) */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
403
src/sort.c
403
src/sort.c
@@ -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 = −
|
||||
}
|
||||
|
||||
if (sortalloc == 0)
|
||||
default_sort_size ();
|
||||
|
||||
if (checkonly)
|
||||
{
|
||||
if (nfiles > 1)
|
||||
|
||||
28
src/sys2.h
28
src/sys2.h
@@ -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
|
||||
|
||||
33
src/tail.c
33
src/tail.c
@@ -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
7
tests/chgrp/Makefile.am
Normal 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
283
tests/chgrp/Makefile.in
Normal 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
89
tests/chgrp/basic
Executable 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
67
tests/chgrp/deref
Executable 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
47
tests/chgrp/recurse
Executable 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
40
tests/dd/skip-seek2
Executable 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
19
tests/group-names
Normal 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
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
28
tests/ls/follow-slink
Executable 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
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -9,4 +9,4 @@ TESTS_ENVIRONMENT = \
|
||||
PATH=`pwd`/../../src:$$PATH \
|
||||
PROG=tail
|
||||
|
||||
TESTS = assert
|
||||
TESTS = assert assert-2
|
||||
|
||||
@@ -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
46
tests/tail-2/assert-2
Executable 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
|
||||
Reference in New Issue
Block a user