mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
Compare commits
123 Commits
CPPI-1_8
...
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 |
1
THANKS
1
THANKS
@@ -198,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
|
||||
|
||||
@@ -1,3 +1,66 @@
|
||||
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.
|
||||
|
||||
@@ -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 \
|
||||
@@ -425,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)
|
||||
@@ -530,10 +535,10 @@ 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 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 \
|
||||
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 \
|
||||
@@ -641,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
|
||||
|
||||
@@ -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,17 +43,23 @@ 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
|
||||
/* 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 const *slash;
|
||||
@@ -78,10 +84,11 @@ dir_name_r (char const *path, char const **result)
|
||||
|
||||
if (path < slash)
|
||||
{
|
||||
slash = memrchr (path, '/', slash - path);
|
||||
size_t len = slash - path;
|
||||
slash = memrchr (path, '/', len);
|
||||
if (BACKSLASH_IS_PATH_SEPARATOR)
|
||||
{
|
||||
char const *b = memrchr (path, '\\', slash - path);
|
||||
char const *b = memrchr (path, '\\', len);
|
||||
if (b && slash < b)
|
||||
slash = b;
|
||||
}
|
||||
@@ -91,27 +98,23 @@ dir_name_r (char const *path, char const **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)
|
||||
{
|
||||
char const *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;
|
||||
}
|
||||
@@ -130,10 +133,14 @@ dir_name (char const *path)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
13
m4/ChangeLog
13
m4/ChangeLog
@@ -1,8 +1,21 @@
|
||||
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>
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ chown.m4 \
|
||||
codeset.m4 \
|
||||
d-ino.m4 \
|
||||
d-type.m4 \
|
||||
dos.m4 \
|
||||
error.m4 \
|
||||
fnmatch.m4 \
|
||||
fpending.m4 \
|
||||
@@ -44,7 +45,6 @@ mbstate_t.m4 \
|
||||
mbswidth.m4 \
|
||||
memcmp.m4 \
|
||||
nanosleep.m4 \
|
||||
off_t-format.m4 \
|
||||
perl.m4 \
|
||||
prereq.m4 \
|
||||
progtest.m4 \
|
||||
|
||||
@@ -126,6 +126,7 @@ chown.m4 \
|
||||
codeset.m4 \
|
||||
d-ino.m4 \
|
||||
d-type.m4 \
|
||||
dos.m4 \
|
||||
error.m4 \
|
||||
fnmatch.m4 \
|
||||
fpending.m4 \
|
||||
@@ -159,7 +160,6 @@ mbstate_t.m4 \
|
||||
mbswidth.m4 \
|
||||
memcmp.m4 \
|
||||
nanosleep.m4 \
|
||||
off_t-format.m4 \
|
||||
perl.m4 \
|
||||
prereq.m4 \
|
||||
progtest.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 28 -*- autoconf -*-
|
||||
#serial 29 -*- autoconf -*-
|
||||
|
||||
dnl Misc type-related macros for fileutils, sh-utils, textutils.
|
||||
|
||||
@@ -70,7 +70,6 @@ AC_DEFUN(jm_MACROS,
|
||||
|
||||
AC_REQUIRE([jm_PREREQ])
|
||||
|
||||
AC_REQUIRE([jm_SYS_OFF_T_PRINTF_FORMAT])
|
||||
AC_REQUIRE([jm_FUNC_LCHOWN])
|
||||
AC_REQUIRE([fetish_FUNC_RMDIR_NOTEMPTY])
|
||||
AC_REQUIRE([jm_FUNC_CHOWN])
|
||||
@@ -224,6 +223,7 @@ AC_DEFUN(jm_MACROS,
|
||||
AC_LIBOBJ(fsusage)
|
||||
AC_LIBOBJ(mountlist)
|
||||
fi
|
||||
AC_REQUIRE([jm_AC_DOS])
|
||||
|
||||
])
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#serial 1 -*- autoconf -*-
|
||||
|
||||
dnl FIXME
|
||||
AC_DEFUN(jm_SYS_OFF_T_PRINTF_FORMAT,
|
||||
[dnl
|
||||
AC_REQUIRE([AC_TYPE_OFF_T])
|
||||
AC_CHECK_HEADERS(string.h stdlinb.h)
|
||||
AC_CACHE_CHECK([for printf format that works with type off_t],
|
||||
jm_cv_sys_off_t_printf_format,
|
||||
[
|
||||
jm_cv_sys_off_t_printf_format=undef
|
||||
for jm_fmt in '' L ll q; do
|
||||
jm_OFF_T_FORMAT="$jm_fmt"
|
||||
export jm_OFF_T_FORMAT
|
||||
AC_TRY_RUN([
|
||||
# include <sys/types.h>
|
||||
# include <stdio.h>
|
||||
# if HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
# if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# endif
|
||||
int
|
||||
main()
|
||||
{
|
||||
static off_t x[] = {1, 255, 65535, 99999999};
|
||||
char buf[50], fmt[50];
|
||||
|
||||
/* this should be one of these values: "", "L", "ll", "q" */
|
||||
char *f = getenv ("jm_OFF_T_FORMAT");
|
||||
|
||||
sprintf (fmt, "%%%sd %%%sx %%%sx %%%sd", f, f, f, f);
|
||||
sprintf (buf, fmt, x[0], x[1], x[2], x[3]);
|
||||
exit (strcmp (buf, "1 ff ffff 99999999"));
|
||||
}
|
||||
], jm_cv_sys_off_t_printf_format=$jm_fmt; break
|
||||
, dnl didn't work
|
||||
dnl Cross compiling -- you lose. Specify it via the cache.
|
||||
)
|
||||
done
|
||||
|
||||
# Die if none of the above worked.
|
||||
# FIXME: If this failure become a problem that we can't work around,
|
||||
# an alternative would be to arrange not to build od.
|
||||
if test "$jm_cv_sys_off_t_printf_format" = undef; then
|
||||
AC_MSG_ERROR(dnl
|
||||
[couldn't find a printf format that works with the type, off_t])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFINE_UNQUOTED(OFF_T_PRINTF_FORMAT_STRING,
|
||||
"$jm_cv_sys_off_t_printf_format",
|
||||
[printf format string for type off_t, without the `%'])
|
||||
])
|
||||
@@ -1,7 +1,127 @@
|
||||
2000-12-03 Jim Meyering <meyering@lucent.com>
|
||||
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.
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
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.
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
2000-12-02 Jim Meyering <meyering@lucent.com>
|
||||
2000-12-17 Jim Meyering <meyering@lucent.com>
|
||||
|
||||
* Version 2.0.12.
|
||||
* 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.
|
||||
|
||||
@@ -1,3 +1,61 @@
|
||||
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,
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
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.
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
182
src/od.c
182
src/od.c
@@ -150,17 +150,15 @@ 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;
|
||||
|
||||
/* 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 size_t string_min;
|
||||
static int flag_dump_strings;
|
||||
@@ -171,15 +169,15 @@ static 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 ((off_t));
|
||||
/* 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;
|
||||
@@ -201,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 "-". */
|
||||
@@ -1042,32 +1040,64 @@ skip (off_t n_skip)
|
||||
return err;
|
||||
}
|
||||
|
||||
static const char *
|
||||
format_address_none (off_t address ATTRIBUTE_UNUSED)
|
||||
static void
|
||||
format_address_none (off_t address ATTRIBUTE_UNUSED, char c ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
static const char *
|
||||
format_address_std (off_t 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 (off_t 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
|
||||
@@ -1107,16 +1137,15 @@ write_block (off_t current_offset, off_t 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)
|
||||
{
|
||||
@@ -1307,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++)
|
||||
@@ -1436,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,
|
||||
@@ -1444,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 ();
|
||||
@@ -1523,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)
|
||||
@@ -1575,42 +1601,21 @@ dump_strings (void)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* There must be exactly one %s format specifier in FORMAT_TEMPLATE.
|
||||
Return the just-malloc'd result of using sprintf to insert
|
||||
OFF_T_PRINTF_FORMAT_STRING into FORMAT_TEMPLATE.
|
||||
Technically, the caller should free this memory, but IMHO it's not
|
||||
worth it in this case. */
|
||||
static char *
|
||||
expand_address_fmt (char const *format_template)
|
||||
{
|
||||
size_t len = strlen (format_template);
|
||||
char *fmt = xmalloc (len + 1);
|
||||
/* Ensure that the literal we're inserting is no longer than the two-byte
|
||||
string `%s' it's replacing. There's also the %%, so technically we don't
|
||||
even need the `+ 1' above. */
|
||||
assert (OFF_T_PRINTF_FORMAT_STRING[0] == 0
|
||||
|| OFF_T_PRINTF_FORMAT_STRING[1] == 0
|
||||
|| OFF_T_PRINTF_FORMAT_STRING[2] == 0);
|
||||
sprintf (fmt, format_template, OFF_T_PRINTF_FORMAT_STRING);
|
||||
return fmt;
|
||||
}
|
||||
|
||||
int
|
||||
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 IF_LINT (= 0);
|
||||
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, "");
|
||||
@@ -1646,8 +1651,8 @@ main (int argc, char **argv)
|
||||
n_specs_allocated = 5;
|
||||
spec = (struct tspec *) xmalloc (n_specs_allocated * sizeof (struct tspec));
|
||||
|
||||
output_address_fmt_string = expand_address_fmt ("%%07%so");
|
||||
format_address = format_address_std;
|
||||
address_base = 8;
|
||||
address_pad_len = 7;
|
||||
flag_dump_strings = 0;
|
||||
|
||||
@@ -1666,22 +1671,21 @@ main (int argc, char **argv)
|
||||
switch (optarg[0])
|
||||
{
|
||||
case 'd':
|
||||
output_address_fmt_string = expand_address_fmt ("%%07%sd");
|
||||
format_address = format_address_std;
|
||||
address_base = 10;
|
||||
address_pad_len = 7;
|
||||
break;
|
||||
case 'o':
|
||||
output_address_fmt_string = expand_address_fmt ("%%07%so");
|
||||
format_address = format_address_std;
|
||||
address_base = 8;
|
||||
address_pad_len = 7;
|
||||
break;
|
||||
case 'x':
|
||||
output_address_fmt_string = expand_address_fmt ("%%06%sx");
|
||||
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;
|
||||
@@ -1785,7 +1789,7 @@ it must be one character from [doxn]"),
|
||||
s_err = xstrtoumax (optarg, NULL, 10, &w_tmp, "");
|
||||
if (s_err != LONGINT_OK)
|
||||
STRTOL_FATAL_ERROR (optarg, _("width specification"), s_err);
|
||||
if (ULONG_MAX < w_tmp)
|
||||
if (SIZE_MAX < w_tmp)
|
||||
error (EXIT_FAILURE, 0, _("%s is too large"), optarg);
|
||||
desired_width = w_tmp;
|
||||
}
|
||||
@@ -1885,29 +1889,17 @@ it must be one character from [doxn]"),
|
||||
|
||||
if (flag_pseudo_start)
|
||||
{
|
||||
static char buf[10];
|
||||
|
||||
if (output_address_fmt_string == NULL)
|
||||
if (format_address == format_address_none)
|
||||
{
|
||||
output_address_fmt_string = expand_address_fmt ("(%%07%so)");
|
||||
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])))
|
||||
@@ -1948,14 +1940,14 @@ it must be one character from [doxn]"),
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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__) */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
127
src/sort.c
127
src/sort.c
@@ -34,6 +34,7 @@
|
||||
#include "hard-locale.h"
|
||||
#include "human.h"
|
||||
#include "memcoll.h"
|
||||
#include "physmem.h"
|
||||
#include "xalloc.h"
|
||||
#include "xstrtol.h"
|
||||
|
||||
@@ -57,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
|
||||
@@ -215,21 +217,19 @@ 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 size_t 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 size_t 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 size_t const linelength = 30;
|
||||
|
||||
/* Maximum number of elements for the array(s) of struct line's, in bytes. */
|
||||
#define LINEALLOC (SORTALLOC / 2)
|
||||
|
||||
/* Array of directory names in which any temporary files are to be created. */
|
||||
static char const **temp_dirs;
|
||||
|
||||
@@ -298,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\
|
||||
@@ -314,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\
|
||||
@@ -558,6 +564,79 @@ 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
|
||||
@@ -631,6 +710,8 @@ fillbuf (struct buffer *buf, FILE *fp)
|
||||
static void
|
||||
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 ();
|
||||
@@ -806,7 +887,7 @@ 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 *)
|
||||
@@ -1360,10 +1441,11 @@ checkfp (FILE *fp, const char *file_name)
|
||||
struct line *disorder_line IF_LINT (= NULL);
|
||||
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);
|
||||
|
||||
@@ -1460,6 +1542,7 @@ 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. */
|
||||
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,
|
||||
@@ -1494,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;
|
||||
}
|
||||
@@ -1721,7 +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));
|
||||
sortalloc / (2 * sizeof (struct line)));
|
||||
|
||||
while (nfiles--)
|
||||
{
|
||||
@@ -2181,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;
|
||||
@@ -2239,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;
|
||||
@@ -2269,6 +2361,9 @@ but lacks following character offset"));
|
||||
files = −
|
||||
}
|
||||
|
||||
if (sortalloc == 0)
|
||||
default_sort_size ();
|
||||
|
||||
if (checkonly)
|
||||
{
|
||||
if (nfiles > 1)
|
||||
|
||||
@@ -171,6 +171,10 @@ char *alloca ();
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h> /* for the definition of UINTMAX_MAX */
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/* Jim Meyering writes:
|
||||
@@ -527,6 +531,10 @@ enum
|
||||
# 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
|
||||
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user