mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
Compare commits
109 Commits
FILEUTILS-
...
FILEUTILS-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94323ee2a7 | ||
|
|
c250ac3ddc | ||
|
|
badacafb98 | ||
|
|
d0672fcf74 | ||
|
|
91e23a4607 | ||
|
|
60d62033fb | ||
|
|
d02a83cba4 | ||
|
|
359c6f7e38 | ||
|
|
1554d14ce1 | ||
|
|
11f093839f | ||
|
|
d1520cea68 | ||
|
|
9cc8d1f6a9 | ||
|
|
48d1df6825 | ||
|
|
3a7457ae6c | ||
|
|
fe76db396c | ||
|
|
dd992130c6 | ||
|
|
02d760e232 | ||
|
|
4905751e2f | ||
|
|
d103085de3 | ||
|
|
9bc1a80b4e | ||
|
|
99ed77dea6 | ||
|
|
bda57be904 | ||
|
|
07053344dc | ||
|
|
f31052628d | ||
|
|
8e03e30c05 | ||
|
|
0ef3c5d7fc | ||
|
|
a06a563ea4 | ||
|
|
9250d1a34f | ||
|
|
a8d7df994f | ||
|
|
b10e58db1b | ||
|
|
a440742330 | ||
|
|
f466b6448a | ||
|
|
9f8bc128f0 | ||
|
|
b0cc976ab9 | ||
|
|
632b63d59c | ||
|
|
1db78f41bf | ||
|
|
7c48860ed8 | ||
|
|
1b0901bb9e | ||
|
|
76a9b4dc10 | ||
|
|
19d33cea2b | ||
|
|
c4ddb7f83a | ||
|
|
431db6c847 | ||
|
|
207d6b3cda | ||
|
|
bbefeb160b | ||
|
|
89d0895332 | ||
|
|
cb5153fefa | ||
|
|
b08eca15fd | ||
|
|
6f922edf2d | ||
|
|
85514c7e0b | ||
|
|
e060631c35 | ||
|
|
cac31ff114 | ||
|
|
f0e23dcff9 | ||
|
|
b3faad27ed | ||
|
|
38121144b2 | ||
|
|
73bc7f0777 | ||
|
|
99571c629e | ||
|
|
4f40ac7422 | ||
|
|
1610efe2fd | ||
|
|
1c70e83474 | ||
|
|
9a06759937 | ||
|
|
6161d60dde | ||
|
|
e3cd439763 | ||
|
|
5e1ffee4d6 | ||
|
|
910287474f | ||
|
|
6faa50c135 | ||
|
|
9fca49f67c | ||
|
|
8a3c0671e0 | ||
|
|
2f7eb5cdf5 | ||
|
|
8fb3745a09 | ||
|
|
aaba44e639 | ||
|
|
1cd88b2b5e | ||
|
|
60695039c0 | ||
|
|
806520fdc0 | ||
|
|
25a8d1f1e9 | ||
|
|
f0e50d53d5 | ||
|
|
40d99818ef | ||
|
|
0d6a1583c6 | ||
|
|
6f48de44ae | ||
|
|
9622d45140 | ||
|
|
890a087101 | ||
|
|
bc2e8cb6ce | ||
|
|
22cce6dadc | ||
|
|
82893aff55 | ||
|
|
c262673191 | ||
|
|
d8071546b1 | ||
|
|
d1e59e17e7 | ||
|
|
9afd1dd692 | ||
|
|
c1e3742914 | ||
|
|
157b3ef61f | ||
|
|
73e540ea1b | ||
|
|
12dd796d8a | ||
|
|
d1c7f62ba8 | ||
|
|
5d76644c3e | ||
|
|
750e5969ff | ||
|
|
6fc1cc1b6a | ||
|
|
9e37b40aa1 | ||
|
|
ebb207dc5a | ||
|
|
d0eeabbc32 | ||
|
|
259838277b | ||
|
|
0b6ee7158e | ||
|
|
3baa7fa854 | ||
|
|
0d13ededce | ||
|
|
a3a4a31c22 | ||
|
|
bf73dd5297 | ||
|
|
6002b5a2ed | ||
|
|
1c9a7ba541 | ||
|
|
e3a368948e | ||
|
|
12bf2f8f8b | ||
|
|
d12ba36443 |
@@ -11,20 +11,25 @@ maintainer-check:
|
||||
$(MAKE) distcheck
|
||||
$(MAKE) my-distcheck
|
||||
|
||||
prev-version := $(shell echo $(VERSION)|tr a-z Xa-y)
|
||||
tag-package = $(shell echo "$(PACKAGE)" | tr a-z A-Z)
|
||||
tag-this-version = $(subst .,_,$(VERSION))
|
||||
tag-prev-version = $(subst .,_,$(prev-version))
|
||||
this-cvs-tag = $(tag-package)-$(tag-this-version)
|
||||
prev-cvs-tag = $(tag-package)-$(tag-prev-version)
|
||||
|
||||
|
||||
# Tag before making distribution. Also, don't make a distribution if
|
||||
# checks fail. Also, make sure the NEWS file is up-to-date.
|
||||
# FIXME: use dist-hook/my-dist like distcheck-hook/my-distcheck.
|
||||
cvs-dist: maintainer-check
|
||||
pkg=`echo "$(PACKAGE)" | tr a-z A-Z`; \
|
||||
ver=`echo "$(VERSION)" | sed 's/\./_/g'`; \
|
||||
tag="$$pkg-$$ver"; \
|
||||
echo tag=$$tag; \
|
||||
if cvs -n log -h README| grep -e $$tag: > /dev/null; then \
|
||||
echo $(this-cvs-tag); \
|
||||
if cvs -n log -h README| grep -e $(this-cvs-tag): > /dev/null; then \
|
||||
echo "VERSION not new; not tagging" 1>&2; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
cvs update po; \
|
||||
cvs tag -c $$tag
|
||||
cvs tag -c $(this-cvs-tag)
|
||||
$(MAKE) dist
|
||||
|
||||
t=./=test
|
||||
@@ -95,13 +100,16 @@ announcement: NEWS ChangeLog $(distdir).tar.gz
|
||||
| grep -v '^\['; \
|
||||
echo; \
|
||||
echo ChangeLog entries:; \
|
||||
sed -n "1,/$v $(PREV_VERSION_REGEXP)/p" \
|
||||
ChangeLog; \
|
||||
find . -name ChangeLog \
|
||||
| xargs cvs diff -up -r$(prev-cvs-tag) -rHEAD \
|
||||
| sed -n 's/^+//p' \
|
||||
| perl -ne 'm!^\+\+ (\./)?! or print,next;' \
|
||||
-e 'print "\n"."*"x70 ."\n"; s///; print; print "*"x70 ."\n"'; \
|
||||
)
|
||||
|
||||
alpha:
|
||||
$(MAKE) cvs-dist
|
||||
$(MAKE) -s announcement > /tmp/announcement
|
||||
$(MAKE) -s announcement > /tmp/announce-$(distdir)
|
||||
ln $(distdir).tar.gz ../release
|
||||
chmod a-w $(distdir).tar.gz
|
||||
@echo =====================================
|
||||
|
||||
2
THANKS
2
THANKS
@@ -64,6 +64,7 @@ Noel Cragg: noel@red-bean.com
|
||||
Olav Morkrid: olav@funcom.com
|
||||
Per Kristian Hove: perhov@math.ntnu.no
|
||||
Peter Eriksson: peter@ifm.liu.se
|
||||
Peter Samuelson: psamuels@sampo.creighton.edu
|
||||
Paul Eggert: eggert@twinsun.com
|
||||
Philippe De Muyter: phdm@macqel.be
|
||||
Rainer Orth: ro@TechFak.Uni-Bielefeld.DE
|
||||
@@ -71,6 +72,7 @@ Ross Ridge: rridge@calum.csclub.uwaterloo.ca
|
||||
Santiago Vila Doncel: sanvila@unex.es
|
||||
Stuart Kemp: skemp@peter.bmc.com
|
||||
Thomas Bushnell, n/BSG: thomas@gnu.ai.mit.edu
|
||||
Ton Hospel: thospel@mail.dma.be
|
||||
Torbjorn Lindgren: tl@funcom.no
|
||||
Tony Leneis: tony@plaza.ds.adp.com
|
||||
Ulrich Drepper: drepper@cygnus.com
|
||||
|
||||
@@ -430,7 +430,7 @@ the file to all users.
|
||||
@cindex numeric modes
|
||||
@cindex file permissions, numeric
|
||||
@cindex octal numbers for file modes
|
||||
File permissions are stored internally as 16 bit integers. As an
|
||||
File permissions are stored internally as integers. As an
|
||||
alternative to giving a symbolic mode, you can give an octal (base 8)
|
||||
number that corresponds to the internal representation of the new mode.
|
||||
This number is always interpreted in octal; you do not have to add a
|
||||
@@ -440,12 +440,13 @@ A numeric mode is usually shorter than the corresponding symbolic
|
||||
mode, but it is limited in that it can not take into account a file's
|
||||
previous permissions; it can only set them absolutely.
|
||||
|
||||
The permissions granted to the user, to other users in the file's group,
|
||||
On most systems, the permissions granted to the user,
|
||||
to other users in the file's group,
|
||||
and to other users not in the file's group are each stored as three
|
||||
bits, which are represented as one octal digit. The three special
|
||||
permissions are also each stored as one bit, and they are as a group
|
||||
represented as another octal digit. Here is how the bits are arranged
|
||||
in the 16 bit integer, starting with the lowest valued bit:
|
||||
represented as another octal digit. Here is how the bits are arranged,
|
||||
starting with the lowest valued bit:
|
||||
|
||||
@example
|
||||
Value in Corresponding
|
||||
|
||||
@@ -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{1999-04-22.19}%
|
||||
\def\texinfoversion{1999-04-25.15}%
|
||||
%
|
||||
% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
||||
% Free Software Foundation, Inc.
|
||||
@@ -3186,8 +3186,12 @@ width0pt\relax} \fi
|
||||
\newcount\subsubsecno \subsubsecno=0
|
||||
|
||||
% This counter is funny since it counts through charcodes of letters A, B, ...
|
||||
% The \the is necessary, despite appearances, because \appendixletter is
|
||||
% expanded while writing the .toc file. \char\appendixno is not
|
||||
% expandable, thus it is written literally, thus all appendixes come out
|
||||
% with the same letter (or @) in the toc without it.
|
||||
\newcount\appendixno \appendixno = `\@
|
||||
\def\appendixletter{\char\appendixno}
|
||||
\def\appendixletter{\char\the\appendixno}
|
||||
|
||||
% Each @chapter defines this as the name of the chapter.
|
||||
% page headings and footings can use it. @section does likewise.
|
||||
|
||||
@@ -2190,8 +2190,10 @@ check that no pair of consecutive lines compares equal.
|
||||
@cindex sort field
|
||||
The recommended, @sc{POSIX}, option for specifying a sort field. The field
|
||||
consists of the part of the line between @var{pos1} and @var{pos2} (or the
|
||||
end of the line, if @var{pos2} is omitted), inclusive. Fields and
|
||||
character positions are numbered starting with 1. See below.
|
||||
end of the line, if @var{pos2} is omitted), @emph{inclusive}.
|
||||
Fields and character positions are numbered starting with 1.
|
||||
So to sort on the second field, you'd use @samp{-k 2,2}
|
||||
See below for more examples.
|
||||
|
||||
@item -z
|
||||
@opindex -z
|
||||
|
||||
@@ -156,9 +156,9 @@ DIST_SOURCES = $(libfu_a_SOURCES)
|
||||
HEADERS = $(noinst_HEADERS)
|
||||
|
||||
DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in TODO alloca.c \
|
||||
chown.c error.c error.h euidaccess.c fileblocks.c fnmatch.c fsusage.c \
|
||||
ftruncate.c getdate.c getgroups.c getline.c group-member.c lchown.c \
|
||||
lstat.c malloc.c memcmp.c memcpy.c memset.c mkdir.c mktime.c \
|
||||
chown.c dup2.c error.c error.h euidaccess.c fileblocks.c fnmatch.c \
|
||||
fsusage.c ftruncate.c getdate.c getgroups.c getline.c group-member.c \
|
||||
lchown.c lstat.c malloc.c memcmp.c memcpy.c memset.c mkdir.c mktime.c \
|
||||
mountlist.c obstack.c obstack.h realloc.c regex.c rename.c rmdir.c \
|
||||
rpmatch.c stat.c stpcpy.c strcasecmp.c strdup.c strftime.c \
|
||||
strncasecmp.c strndup.c strstr.c strtol.c strtoul.c strtoull.c \
|
||||
@@ -170,23 +170,24 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
GZIP_ENV = --best
|
||||
DEP_FILES = .deps/addext.P .deps/alloca.P .deps/argmatch.P \
|
||||
.deps/backupfile.P .deps/basename.P .deps/chown.P .deps/closeout.P \
|
||||
.deps/dirname.P .deps/error.P .deps/euidaccess.P .deps/exclude.P \
|
||||
.deps/fileblocks.P .deps/filemode.P .deps/fnmatch.P .deps/fsusage.P \
|
||||
.deps/ftruncate.P .deps/full-write.P .deps/getdate.P .deps/getgroups.P \
|
||||
.deps/getline.P .deps/getopt.P .deps/getopt1.P .deps/group-member.P \
|
||||
.deps/hash.P .deps/human.P .deps/idcache.P .deps/isdir.P .deps/lchown.P \
|
||||
.deps/long-options.P .deps/lstat.P .deps/makepath.P .deps/malloc.P \
|
||||
.deps/memcmp.P .deps/memcpy.P .deps/memset.P .deps/mkdir.P \
|
||||
.deps/mktime.P .deps/modechange.P .deps/mountlist.P .deps/obstack.P \
|
||||
.deps/path-concat.P .deps/posixtm.P .deps/quotearg.P .deps/realloc.P \
|
||||
.deps/regex.P .deps/rename.P .deps/rmdir.P .deps/rpmatch.P \
|
||||
.deps/safe-read.P .deps/save-cwd.P .deps/savedir.P .deps/stat.P \
|
||||
.deps/stpcpy.P .deps/strcasecmp.P .deps/strdup.P .deps/strftime.P \
|
||||
.deps/stripslash.P .deps/strncasecmp.P .deps/strndup.P .deps/strstr.P \
|
||||
.deps/strtol.P .deps/strtoul.P .deps/strtoull.P .deps/strtoumax.P \
|
||||
.deps/strverscmp.P .deps/userspec.P .deps/utime.P .deps/version-etc.P \
|
||||
.deps/xgetcwd.P .deps/xmalloc.P .deps/xstrdup.P .deps/xstrtol.P \
|
||||
.deps/xstrtoul.P .deps/xstrtoumax.P .deps/yesno.P
|
||||
.deps/dirname.P .deps/dup2.P .deps/error.P .deps/euidaccess.P \
|
||||
.deps/exclude.P .deps/fileblocks.P .deps/filemode.P .deps/fnmatch.P \
|
||||
.deps/fsusage.P .deps/ftruncate.P .deps/full-write.P .deps/getdate.P \
|
||||
.deps/getgroups.P .deps/getline.P .deps/getopt.P .deps/getopt1.P \
|
||||
.deps/group-member.P .deps/hash.P .deps/human.P .deps/idcache.P \
|
||||
.deps/isdir.P .deps/lchown.P .deps/long-options.P .deps/lstat.P \
|
||||
.deps/makepath.P .deps/malloc.P .deps/memcmp.P .deps/memcpy.P \
|
||||
.deps/memset.P .deps/mkdir.P .deps/mktime.P .deps/modechange.P \
|
||||
.deps/mountlist.P .deps/obstack.P .deps/path-concat.P .deps/posixtm.P \
|
||||
.deps/quotearg.P .deps/realloc.P .deps/regex.P .deps/rename.P \
|
||||
.deps/rmdir.P .deps/rpmatch.P .deps/safe-read.P .deps/save-cwd.P \
|
||||
.deps/savedir.P .deps/stat.P .deps/stpcpy.P .deps/strcasecmp.P \
|
||||
.deps/strdup.P .deps/strftime.P .deps/stripslash.P .deps/strncasecmp.P \
|
||||
.deps/strndup.P .deps/strstr.P .deps/strtol.P .deps/strtoul.P \
|
||||
.deps/strtoull.P .deps/strtoumax.P .deps/strverscmp.P .deps/userspec.P \
|
||||
.deps/utime.P .deps/version-etc.P .deps/xgetcwd.P .deps/xmalloc.P \
|
||||
.deps/xstrdup.P .deps/xstrtol.P .deps/xstrtoul.P .deps/xstrtoumax.P \
|
||||
.deps/yesno.P
|
||||
SOURCES = $(libfu_a_SOURCES)
|
||||
OBJECTS = $(am_libfu_a_OBJECTS)
|
||||
|
||||
@@ -293,6 +294,8 @@ closeout_.c: closeout.c $(ANSI2KNR)
|
||||
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/closeout.c; then echo $(srcdir)/closeout.c; else echo closeout.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > closeout_.c
|
||||
dirname_.c: dirname.c $(ANSI2KNR)
|
||||
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/dirname.c; then echo $(srcdir)/dirname.c; else echo dirname.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > dirname_.c
|
||||
dup2_.c: dup2.c $(ANSI2KNR)
|
||||
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/dup2.c; then echo $(srcdir)/dup2.c; else echo dup2.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > dup2_.c
|
||||
error_.c: error.c $(ANSI2KNR)
|
||||
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/error.c; then echo $(srcdir)/error.c; else echo error.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > error_.c
|
||||
euidaccess_.c: euidaccess.c $(ANSI2KNR)
|
||||
@@ -428,18 +431,19 @@ xstrtoumax_.c: xstrtoumax.c $(ANSI2KNR)
|
||||
yesno_.c: yesno.c $(ANSI2KNR)
|
||||
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/yesno.c; then echo $(srcdir)/yesno.c; else echo yesno.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > yesno_.c
|
||||
addext_.o alloca_.o argmatch_.o backupfile_.o basename_.o chown_.o \
|
||||
closeout_.o dirname_.o error_.o euidaccess_.o exclude_.o fileblocks_.o \
|
||||
filemode_.o fnmatch_.o fsusage_.o ftruncate_.o full-write_.o getdate_.o \
|
||||
getgroups_.o getline_.o getopt_.o getopt1_.o group-member_.o hash_.o \
|
||||
human_.o idcache_.o isdir_.o lchown_.o long-options_.o lstat_.o \
|
||||
makepath_.o malloc_.o memcmp_.o memcpy_.o memset_.o mkdir_.o mktime_.o \
|
||||
modechange_.o mountlist_.o obstack_.o path-concat_.o posixtm_.o \
|
||||
quotearg_.o realloc_.o regex_.o rename_.o rmdir_.o rpmatch_.o \
|
||||
safe-read_.o save-cwd_.o savedir_.o stat_.o stpcpy_.o strcasecmp_.o \
|
||||
strdup_.o strftime_.o stripslash_.o strncasecmp_.o strndup_.o strstr_.o \
|
||||
strtol_.o strtoul_.o strtoull_.o strtoumax_.o strverscmp_.o userspec_.o \
|
||||
utime_.o version-etc_.o xgetcwd_.o xmalloc_.o xstrdup_.o xstrtol_.o \
|
||||
xstrtoul_.o xstrtoumax_.o yesno_.o : $(ANSI2KNR)
|
||||
closeout_.o dirname_.o dup2_.o error_.o euidaccess_.o exclude_.o \
|
||||
fileblocks_.o filemode_.o fnmatch_.o fsusage_.o ftruncate_.o \
|
||||
full-write_.o getdate_.o getgroups_.o getline_.o getopt_.o getopt1_.o \
|
||||
group-member_.o hash_.o human_.o idcache_.o isdir_.o lchown_.o \
|
||||
long-options_.o lstat_.o makepath_.o malloc_.o memcmp_.o memcpy_.o \
|
||||
memset_.o mkdir_.o mktime_.o modechange_.o mountlist_.o obstack_.o \
|
||||
path-concat_.o posixtm_.o quotearg_.o realloc_.o regex_.o rename_.o \
|
||||
rmdir_.o rpmatch_.o safe-read_.o save-cwd_.o savedir_.o stat_.o \
|
||||
stpcpy_.o strcasecmp_.o strdup_.o strftime_.o stripslash_.o \
|
||||
strncasecmp_.o strndup_.o strstr_.o strtol_.o strtoul_.o strtoull_.o \
|
||||
strtoumax_.o strverscmp_.o userspec_.o utime_.o version-etc_.o \
|
||||
xgetcwd_.o xmalloc_.o xstrdup_.o xstrtol_.o xstrtoul_.o xstrtoumax_.o \
|
||||
yesno_.o : $(ANSI2KNR)
|
||||
.y.c:
|
||||
$(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c
|
||||
if test -f y.tab.h; then \
|
||||
|
||||
66
lib/dup2.c
Normal file
66
lib/dup2.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/* Duplicate an open file descriptor to a specified file descriptor.
|
||||
Copyright 1999 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 <errno.h>
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef F_DUPFD
|
||||
static int
|
||||
dupfd (int fd, int desired_fd)
|
||||
{
|
||||
int duplicated_fd = dup (fd);
|
||||
if (duplicated_fd < 0 || duplicated_fd == desired_fd)
|
||||
return duplicated_fd;
|
||||
else
|
||||
{
|
||||
int r = dupfd (fd, desired_fd);
|
||||
int e = errno;
|
||||
close (duplicated_fd);
|
||||
errno = e;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
dup2 (int fd, int desired_fd)
|
||||
{
|
||||
if (fd == desired_fd)
|
||||
return fd;
|
||||
close (desired_fd);
|
||||
#ifdef F_DUPFD
|
||||
return fcntl (fd, F_DUPFD, desired_fd);
|
||||
#else
|
||||
return dupfd (fd, desired_fd);
|
||||
#endif
|
||||
}
|
||||
@@ -48,6 +48,25 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !S_IRGRP
|
||||
# define S_IRGRP (S_IRUSR >> 3)
|
||||
#endif
|
||||
#if !S_IWGRP
|
||||
# define S_IWGRP (S_IWUSR >> 3)
|
||||
#endif
|
||||
#if !S_IXGRP
|
||||
# define S_IXGRP (S_IXUSR >> 3)
|
||||
#endif
|
||||
#if !S_IROTH
|
||||
# define S_IROTH (S_IRUSR >> 6)
|
||||
#endif
|
||||
#if !S_IWOTH
|
||||
# define S_IWOTH (S_IWUSR >> 6)
|
||||
#endif
|
||||
#if !S_IXOTH
|
||||
# define S_IXOTH (S_IXUSR >> 6)
|
||||
#endif
|
||||
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
# undef S_ISBLK
|
||||
# undef S_ISCHR
|
||||
@@ -93,22 +112,11 @@
|
||||
# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
|
||||
#endif
|
||||
|
||||
/* Look at read, write, and execute bits in BITS and set
|
||||
flags in CHARS accordingly. */
|
||||
|
||||
static void
|
||||
rwx (short unsigned int bits, char *chars)
|
||||
{
|
||||
chars[0] = (bits & S_IRUSR) ? 'r' : '-';
|
||||
chars[1] = (bits & S_IWUSR) ? 'w' : '-';
|
||||
chars[2] = (bits & S_IXUSR) ? 'x' : '-';
|
||||
}
|
||||
|
||||
/* Set the 's' and 't' flags in file attributes string CHARS,
|
||||
according to the file mode BITS. */
|
||||
|
||||
static void
|
||||
setst (short unsigned int bits, char *chars)
|
||||
setst (mode_t bits, char *chars)
|
||||
{
|
||||
#ifdef S_ISUID
|
||||
if (bits & S_ISUID)
|
||||
@@ -157,7 +165,7 @@ setst (short unsigned int bits, char *chars)
|
||||
'?' for any other file type. */
|
||||
|
||||
static char
|
||||
ftypelet (long int bits)
|
||||
ftypelet (mode_t bits)
|
||||
{
|
||||
#ifdef S_ISBLK
|
||||
if (S_ISBLK (bits))
|
||||
@@ -216,12 +224,18 @@ ftypelet (long int bits)
|
||||
is given as an argument. */
|
||||
|
||||
void
|
||||
mode_string (short unsigned int mode, char *str)
|
||||
mode_string (mode_t mode, char *str)
|
||||
{
|
||||
str[0] = ftypelet ((long) mode);
|
||||
rwx ((mode & 0700) << 0, &str[1]);
|
||||
rwx ((mode & 0070) << 3, &str[4]);
|
||||
rwx ((mode & 0007) << 6, &str[7]);
|
||||
str[0] = ftypelet (mode);
|
||||
str[1] = mode & S_IRUSR ? 'r' : '-';
|
||||
str[2] = mode & S_IWUSR ? 'w' : '-';
|
||||
str[3] = mode & S_IXUSR ? 'x' : '-';
|
||||
str[4] = mode & S_IRGRP ? 'r' : '-';
|
||||
str[5] = mode & S_IWGRP ? 'w' : '-';
|
||||
str[6] = mode & S_IXGRP ? 'x' : '-';
|
||||
str[7] = mode & S_IROTH ? 'r' : '-';
|
||||
str[8] = mode & S_IWOTH ? 'w' : '-';
|
||||
str[9] = mode & S_IXOTH ? 'x' : '-';
|
||||
setst (mode, str);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
#ifndef PARAMS
|
||||
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
|
||||
# define PARAMS(Args) Args
|
||||
# else
|
||||
# define PARAMS(Args) ()
|
||||
# endif
|
||||
#endif
|
||||
#ifndef FILEMODE_H_
|
||||
|
||||
void mode_string PARAMS ((short unsigned int mode, char *str));
|
||||
# if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# endif
|
||||
|
||||
# include <sys/types.h>
|
||||
|
||||
# ifndef PARAMS
|
||||
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
|
||||
# define PARAMS(Args) Args
|
||||
# else
|
||||
# define PARAMS(Args) ()
|
||||
# endif
|
||||
# endif
|
||||
|
||||
void mode_string PARAMS ((mode_t mode, char *str));
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,10 +23,6 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
#ifndef HUMAN_H_
|
||||
# define HUMAN_H_ 1
|
||||
|
||||
# if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
# endif
|
||||
|
||||
/* A conservative bound on the maximum length of a human-readable string.
|
||||
The output can be the product of the largest uintmax_t and the largest int,
|
||||
so add their sizes before converting to a bound on digits. */
|
||||
|
||||
@@ -71,16 +71,34 @@ extern int errno;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef S_ISUID
|
||||
# define S_ISUID 04000
|
||||
#endif
|
||||
#ifndef S_ISGID
|
||||
# define S_ISGID 02000
|
||||
#endif
|
||||
#ifndef S_ISVTX
|
||||
# define S_ISVTX 01000
|
||||
#endif
|
||||
#ifndef S_IRUSR
|
||||
# define S_IRUSR 0200
|
||||
#endif
|
||||
#ifndef S_IWUSR
|
||||
# define S_IWUSR 0200
|
||||
#endif
|
||||
|
||||
#ifndef S_IXUSR
|
||||
# define S_IXUSR 0100
|
||||
#endif
|
||||
|
||||
#ifndef S_IRWXU
|
||||
# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
|
||||
#endif
|
||||
|
||||
#define WX_USR (S_IWUSR | S_IXUSR)
|
||||
|
||||
/* Include this before libintl.h so we get our definition of PARAMS. */
|
||||
#include "makepath.h"
|
||||
|
||||
#if HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
#endif
|
||||
@@ -98,7 +116,6 @@ typedef int gid_t;
|
||||
#endif
|
||||
|
||||
#include "save-cwd.h"
|
||||
#include "makepath.h"
|
||||
#include "error.h"
|
||||
|
||||
void strip_trailing_slashes ();
|
||||
@@ -145,6 +162,7 @@ make_dir (const char *dir, const char *dirpath, mode_t mode, int *created_dir_p)
|
||||
if (!created_dir)
|
||||
{
|
||||
struct stat stats;
|
||||
int saved_errno = errno;
|
||||
|
||||
/* The mkdir and stat calls below may appear to be reversed.
|
||||
They are not. It is important to call mkdir first and then to
|
||||
@@ -156,7 +174,7 @@ make_dir (const char *dir, const char *dirpath, mode_t mode, int *created_dir_p)
|
||||
|
||||
if (stat (dir, &stats))
|
||||
{
|
||||
error (0, errno, _("cannot create directory `%s'"), dirpath);
|
||||
error (0, saved_errno, _("cannot create directory `%s'"), dirpath);
|
||||
fail = 1;
|
||||
}
|
||||
else if (!S_ISDIR (stats.st_mode))
|
||||
@@ -223,7 +241,7 @@ make_path (const char *argpath,
|
||||
char *dirpath;
|
||||
|
||||
/* Temporarily relax umask in case it's overly restrictive. */
|
||||
int oldmask = umask (0);
|
||||
mode_t oldmask = umask (0);
|
||||
|
||||
/* Make a copy of ARGPATH that we can scribble NULs on. */
|
||||
dirpath = (char *) alloca (strlen (argpath) + 1);
|
||||
@@ -235,9 +253,9 @@ make_path (const char *argpath,
|
||||
their owners, we need to fix their permissions after making them. */
|
||||
if (((parent_mode & WX_USR) != WX_USR)
|
||||
|| ((owner != (uid_t) -1 || group != (gid_t) -1)
|
||||
&& (parent_mode & 07000) != 0))
|
||||
&& (parent_mode & (S_ISUID | S_ISGID | S_ISVTX)) != 0))
|
||||
{
|
||||
tmp_mode = 0700;
|
||||
tmp_mode = S_IRWXU;
|
||||
re_protect = 1;
|
||||
}
|
||||
else
|
||||
@@ -363,7 +381,8 @@ make_path (const char *argpath,
|
||||
retval = 1;
|
||||
}
|
||||
/* chown may have turned off some permission bits we wanted. */
|
||||
if ((mode & 07000) != 0 && chmod (basename_dir, mode))
|
||||
if ((mode & (S_ISUID | S_ISGID | S_ISVTX))
|
||||
&& chmod (basename_dir, mode))
|
||||
{
|
||||
error (0, errno, _("cannot chmod %s"), dirpath);
|
||||
retval = 1;
|
||||
|
||||
18
lib/mkdir.c
18
lib/mkdir.c
@@ -34,6 +34,16 @@ extern int errno;
|
||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#ifndef S_IRWXU
|
||||
# define S_IRWXU 0700
|
||||
#endif
|
||||
#ifndef S_IRWXG
|
||||
# define S_IRWXG 0070
|
||||
#endif
|
||||
#ifndef S_IRWXO
|
||||
# define S_IRWXO 0007
|
||||
#endif
|
||||
|
||||
/* mkdir adapted from GNU tar. */
|
||||
|
||||
/* Make directory DPATH, with permission mode DMODE.
|
||||
@@ -48,9 +58,10 @@ extern int errno;
|
||||
subroutine didn't return EEXIST. It does now. */
|
||||
|
||||
int
|
||||
mkdir (const char *dpath, int dmode)
|
||||
mkdir (const char *dpath, mode_t dmode)
|
||||
{
|
||||
pid_t cpid;
|
||||
mode_t mode;
|
||||
int status;
|
||||
struct stat statbuf;
|
||||
|
||||
@@ -75,8 +86,9 @@ mkdir (const char *dpath, int dmode)
|
||||
process is going away anyway, we zap its umask.
|
||||
This won't suffice to set SUID, SGID, etc. on this
|
||||
directory, so the parent process calls chmod afterward. */
|
||||
status = umask (0); /* Get current umask. */
|
||||
umask (status | (0777 & ~dmode)); /* Set for mkdir. */
|
||||
mode = umask (0); /* Get current umask. */
|
||||
/* Set for mkdir. */
|
||||
umask (mode | ((S_IRWXU | S_IRWXG | S_IRWXO) & ~dmode));
|
||||
execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
|
||||
_exit (1);
|
||||
|
||||
|
||||
155
lib/modechange.c
155
lib/modechange.c
@@ -28,9 +28,9 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "modechange.h"
|
||||
#include <sys/stat.h>
|
||||
#include "xstrtol.h"
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
@@ -50,34 +50,65 @@ char *malloc ();
|
||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#ifndef S_ISUID
|
||||
# define S_ISUID 04000
|
||||
#endif
|
||||
#ifndef S_ISGID
|
||||
# define S_ISGID 04000
|
||||
#endif
|
||||
#ifndef S_ISVTX
|
||||
# define S_ISVTX 01000
|
||||
#endif
|
||||
#ifndef S_IRUSR
|
||||
# define S_IRUSR 0400
|
||||
#endif
|
||||
#ifndef S_IWUSR
|
||||
# define S_IWUSR 0200
|
||||
#endif
|
||||
#ifndef S_IXUSR
|
||||
# define S_IXUSR 0100
|
||||
#endif
|
||||
#ifndef S_IRGRP
|
||||
# define S_IRGRP 0040
|
||||
#endif
|
||||
#ifndef S_IWGRP
|
||||
# define S_IWGRP 0020
|
||||
#endif
|
||||
#ifndef S_IXGRP
|
||||
# define S_IXGRP 0010
|
||||
#endif
|
||||
#ifndef S_IROTH
|
||||
# define S_IROTH 0004
|
||||
#endif
|
||||
#ifndef S_IWOTH
|
||||
# define S_IWOTH 0002
|
||||
#endif
|
||||
#ifndef S_IXOTH
|
||||
# define S_IXOTH 0001
|
||||
#endif
|
||||
#ifndef S_IRWXU
|
||||
# define S_IRWXU 0700
|
||||
#endif
|
||||
#ifndef S_IRWXG
|
||||
# define S_IRWXG 0070
|
||||
#endif
|
||||
#ifndef S_IRWXO
|
||||
# define S_IRWXO 0007
|
||||
#endif
|
||||
|
||||
/* All the mode bits that can be affected by chmod. */
|
||||
#define CHMOD_MODE_BITS \
|
||||
(S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
|
||||
|
||||
/* Return newly allocated memory to hold one element of type TYPE. */
|
||||
#define talloc(type) ((type *) malloc (sizeof (type)))
|
||||
|
||||
#define isodigit(c) ((c) >= '0' && (c) <= '7')
|
||||
|
||||
/* Return a positive integer containing the value of the ASCII
|
||||
octal number S. If S is not an octal number, return -1. */
|
||||
|
||||
static int
|
||||
oatoi (const char *s)
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (*s == 0)
|
||||
return -1;
|
||||
for (i = 0; isodigit (*s); ++s)
|
||||
i = i * 8 + *s - '0';
|
||||
if (*s)
|
||||
return -1;
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Create a mode_change entry with the specified `=ddd'-style
|
||||
mode change operation, where NEW_MODE is `ddd'. Return the
|
||||
new entry, or NULL upon failure. */
|
||||
|
||||
static struct mode_change *
|
||||
make_node_op_equals (int new_mode)
|
||||
make_node_op_equals (mode_t new_mode)
|
||||
{
|
||||
struct mode_change *p;
|
||||
p = talloc (struct mode_change);
|
||||
@@ -87,7 +118,7 @@ make_node_op_equals (int new_mode)
|
||||
p->op = '=';
|
||||
p->flags = 0;
|
||||
p->value = new_mode;
|
||||
p->affected = 07777; /* Affect all permissions. */
|
||||
p->affected = CHMOD_MODE_BITS; /* Affect all permissions. */
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -126,21 +157,21 @@ mode_compile (const char *mode_string, unsigned int masked_ops)
|
||||
{
|
||||
struct mode_change *head; /* First element of the linked list. */
|
||||
struct mode_change *tail; /* An element of the linked list. */
|
||||
int i; /* General purpose temporary. */
|
||||
int umask_value; /* The umask value (surprise). */
|
||||
unsigned long mode_value; /* The mode value, if octal. */
|
||||
char *string_end; /* Pointer to end of parsed value. */
|
||||
mode_t umask_value; /* The umask value (surprise). */
|
||||
|
||||
head = NULL;
|
||||
#ifdef lint
|
||||
tail = NULL;
|
||||
#endif
|
||||
|
||||
i = oatoi (mode_string);
|
||||
if (i >= 0)
|
||||
if (xstrtoul (mode_string, &string_end, 8, &mode_value, "") == LONGINT_OK)
|
||||
{
|
||||
struct mode_change *p;
|
||||
if (i > 07777)
|
||||
if (mode_value > CHMOD_MODE_BITS)
|
||||
return MODE_INVALID;
|
||||
p = make_node_op_equals (i);
|
||||
p = make_node_op_equals ((mode_t) mode_value);
|
||||
if (p == NULL)
|
||||
return MODE_MEMORY_EXHAUSTED;
|
||||
mode_append_entry (&head, &tail, p);
|
||||
@@ -155,9 +186,9 @@ mode_compile (const char *mode_string, unsigned int masked_ops)
|
||||
do
|
||||
{
|
||||
/* Which bits in the mode are operated on. */
|
||||
unsigned short affected_bits = 0;
|
||||
mode_t affected_bits = 0;
|
||||
/* `affected_bits' modified by umask. */
|
||||
unsigned short affected_masked;
|
||||
mode_t affected_masked;
|
||||
/* Operators to actually use umask on. */
|
||||
unsigned ops_to_mask = 0;
|
||||
|
||||
@@ -170,16 +201,16 @@ mode_compile (const char *mode_string, unsigned int masked_ops)
|
||||
switch (*mode_string)
|
||||
{
|
||||
case 'u':
|
||||
affected_bits |= 04700;
|
||||
affected_bits |= S_ISUID | S_IRWXU;
|
||||
break;
|
||||
case 'g':
|
||||
affected_bits |= 02070;
|
||||
affected_bits |= S_ISGID | S_IRWXG;
|
||||
break;
|
||||
case 'o':
|
||||
affected_bits |= 01007;
|
||||
affected_bits |= S_ISVTX | S_IRWXO;
|
||||
break;
|
||||
case 'a':
|
||||
affected_bits |= 07777;
|
||||
affected_bits |= CHMOD_MODE_BITS;
|
||||
break;
|
||||
default:
|
||||
goto no_more_affected;
|
||||
@@ -193,7 +224,7 @@ mode_compile (const char *mode_string, unsigned int masked_ops)
|
||||
else
|
||||
{
|
||||
who_specified_p = 0;
|
||||
affected_bits = 07777;
|
||||
affected_bits = CHMOD_MODE_BITS;
|
||||
ops_to_mask = masked_ops;
|
||||
}
|
||||
|
||||
@@ -238,31 +269,34 @@ mode_compile (const char *mode_string, unsigned int masked_ops)
|
||||
switch (*mode_string)
|
||||
{
|
||||
case 'r':
|
||||
change->value |= 00444 & affected_masked;
|
||||
change->value |= ((S_IRUSR | S_IRGRP | S_IROTH)
|
||||
& affected_masked);
|
||||
break;
|
||||
case 'w':
|
||||
change->value |= 00222 & affected_masked;
|
||||
change->value |= ((S_IWUSR | S_IWGRP | S_IWOTH)
|
||||
& affected_masked);
|
||||
break;
|
||||
case 'X':
|
||||
change->flags |= MODE_X_IF_ANY_X;
|
||||
/* Fall through. */
|
||||
case 'x':
|
||||
change->value |= 00111 & affected_masked;
|
||||
change->value |= ((S_IXUSR | S_IXGRP | S_IXOTH)
|
||||
& affected_masked);
|
||||
break;
|
||||
case 's':
|
||||
/* Set the setuid/gid bits if `u' or `g' is selected. */
|
||||
change->value |= 06000 & affected_masked;
|
||||
change->value |= (S_ISUID | S_ISGID) & affected_masked;
|
||||
break;
|
||||
case 't':
|
||||
/* Set the "save text image" bit if `o' is selected. */
|
||||
change->value |= 01000 & affected_masked;
|
||||
change->value |= S_ISVTX & affected_masked;
|
||||
break;
|
||||
case 'u':
|
||||
/* Set the affected bits to the value of the `u' bits
|
||||
on the same file. */
|
||||
if (change->value)
|
||||
goto invalid;
|
||||
change->value = 00700;
|
||||
change->value = S_IRWXU;
|
||||
change->flags |= MODE_COPY_EXISTING;
|
||||
break;
|
||||
case 'g':
|
||||
@@ -270,7 +304,7 @@ mode_compile (const char *mode_string, unsigned int masked_ops)
|
||||
on the same file. */
|
||||
if (change->value)
|
||||
goto invalid;
|
||||
change->value = 00070;
|
||||
change->value = S_IRWXG;
|
||||
change->flags |= MODE_COPY_EXISTING;
|
||||
break;
|
||||
case 'o':
|
||||
@@ -278,7 +312,7 @@ mode_compile (const char *mode_string, unsigned int masked_ops)
|
||||
on the same file. */
|
||||
if (change->value)
|
||||
goto invalid;
|
||||
change->value = 00007;
|
||||
change->value = S_IRWXO;
|
||||
change->flags |= MODE_COPY_EXISTING;
|
||||
break;
|
||||
default:
|
||||
@@ -313,7 +347,7 @@ mode_create_from_ref (const char *ref_file)
|
||||
|
||||
change->op = '=';
|
||||
change->flags = 0;
|
||||
change->affected = 07777;
|
||||
change->affected = CHMOD_MODE_BITS;
|
||||
change->value = ref_stats.st_mode;
|
||||
change->next = NULL;
|
||||
|
||||
@@ -325,13 +359,13 @@ mode_create_from_ref (const char *ref_file)
|
||||
change affects it even if no execute bits were set in OLDMODE.
|
||||
The returned value has the S_IFMT bits cleared. */
|
||||
|
||||
unsigned short
|
||||
mode_adjust (unsigned int oldmode, const struct mode_change *changes)
|
||||
mode_t
|
||||
mode_adjust (mode_t oldmode, const struct mode_change *changes)
|
||||
{
|
||||
unsigned short newmode; /* The adjusted mode and one operand. */
|
||||
unsigned short value; /* The other operand. */
|
||||
mode_t newmode; /* The adjusted mode and one operand. */
|
||||
mode_t value; /* The other operand. */
|
||||
|
||||
newmode = oldmode & 07777;
|
||||
newmode = oldmode & CHMOD_MODE_BITS;
|
||||
|
||||
for (; changes; changes = changes->next)
|
||||
{
|
||||
@@ -341,15 +375,21 @@ mode_adjust (unsigned int oldmode, const struct mode_change *changes)
|
||||
the mask `changes->value'. */
|
||||
value = newmode & changes->value;
|
||||
|
||||
if (changes->value & 00700)
|
||||
if (changes->value & S_IRWXU)
|
||||
/* Copy `u' permissions onto `g' and `o'. */
|
||||
value |= (value >> 3) | (value >> 6);
|
||||
else if (changes->value & 00070)
|
||||
value |= ((value & S_IRUSR ? S_IRGRP | S_IROTH : 0)
|
||||
| (value & S_IWUSR ? S_IWGRP | S_IROTH : 0)
|
||||
| (value & S_IXUSR ? S_IXGRP | S_IXOTH : 0));
|
||||
else if (changes->value & S_IRWXG)
|
||||
/* Copy `g' permissions onto `u' and `o'. */
|
||||
value |= (value << 3) | (value >> 3);
|
||||
value |= ((value & S_IRGRP ? S_IRUSR | S_IROTH : 0)
|
||||
| (value & S_IWGRP ? S_IWUSR | S_IROTH : 0)
|
||||
| (value & S_IXGRP ? S_IXUSR | S_IXOTH : 0));
|
||||
else
|
||||
/* Copy `o' permissions onto `u' and `g'. */
|
||||
value |= (value << 3) | (value << 6);
|
||||
value |= ((value & S_IROTH ? S_IRUSR | S_IRGRP : 0)
|
||||
| (value & S_IWOTH ? S_IWUSR | S_IRGRP : 0)
|
||||
| (value & S_IXOTH ? S_IXUSR | S_IXGRP : 0));
|
||||
|
||||
/* In order to change only `u', `g', or `o' permissions,
|
||||
or some combination thereof, clear unselected bits.
|
||||
@@ -365,8 +405,9 @@ mode_adjust (unsigned int oldmode, const struct mode_change *changes)
|
||||
directory and no execute bits are already set. */
|
||||
if ((changes->flags & MODE_X_IF_ANY_X)
|
||||
&& !S_ISDIR (oldmode)
|
||||
&& (newmode & 00111) == 0)
|
||||
value &= ~00111; /* Clear the execute bits. */
|
||||
&& (newmode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)
|
||||
/* Clear the execute bits. */
|
||||
value &= ~ (S_IXUSR | S_IXGRP | S_IXOTH);
|
||||
}
|
||||
|
||||
switch (changes->op)
|
||||
|
||||
@@ -20,6 +20,12 @@
|
||||
#if ! defined MODECHANGE_H_
|
||||
# define MODECHANGE_H_
|
||||
|
||||
# if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# endif
|
||||
|
||||
# include <sys/types.h>
|
||||
|
||||
/* Affect the execute bits only if at least one execute bit is set already,
|
||||
or if the file is a directory. */
|
||||
# define MODE_X_IF_ANY_X 01
|
||||
@@ -33,8 +39,8 @@ struct mode_change
|
||||
{
|
||||
char op; /* One of "=+-". */
|
||||
char flags; /* Special operations. */
|
||||
unsigned short affected; /* Set for u/g/o/s/s/t, if to be affected. */
|
||||
unsigned short value; /* Bits to add/remove. */
|
||||
mode_t affected; /* Set for u/g/o/s/s/t, if to be affected. */
|
||||
mode_t value; /* Bits to add/remove. */
|
||||
struct mode_change *next; /* Link to next change in list. */
|
||||
};
|
||||
|
||||
@@ -59,7 +65,7 @@ struct mode_change
|
||||
|
||||
struct mode_change *mode_compile PARAMS ((const char *, unsigned));
|
||||
struct mode_change *mode_create_from_ref PARAMS ((const char *));
|
||||
unsigned short mode_adjust PARAMS ((unsigned, const struct mode_change *));
|
||||
mode_t mode_adjust PARAMS ((mode_t, const struct mode_change *));
|
||||
void mode_free PARAMS ((struct mode_change *));
|
||||
|
||||
#endif
|
||||
|
||||
@@ -66,13 +66,16 @@ read_utmp (const char *filename, int *n_entries, STRUCT_UTMP **utmp_buf)
|
||||
STRUCT_UTMP *u;
|
||||
STRUCT_UTMP *utmp = NULL;
|
||||
|
||||
if (utmpname (filename))
|
||||
return 1;
|
||||
/* Ignore the return value for now.
|
||||
Solaris' utmpname returns 1 upon success -- which is contrary
|
||||
to what the GNU libc version does. In addition, older GNU libc
|
||||
versions are actually void. */
|
||||
UTMP_NAME_FUNCTION (filename);
|
||||
|
||||
setutent ();
|
||||
SET_UTMP_ENT ();
|
||||
|
||||
n_read = 0;
|
||||
while ((u = getutent ()) != NULL)
|
||||
while ((u = GET_UTMP_ENT ()) != NULL)
|
||||
{
|
||||
++n_read;
|
||||
utmp = (STRUCT_UTMP *) realloc (utmp, n_read * sizeof (STRUCT_UTMP));
|
||||
@@ -81,7 +84,7 @@ read_utmp (const char *filename, int *n_entries, STRUCT_UTMP **utmp_buf)
|
||||
utmp[n_read - 1] = *u;
|
||||
}
|
||||
|
||||
endutent ();
|
||||
END_UTMP_ENT ();
|
||||
|
||||
*n_entries = n_read;
|
||||
*utmp_buf = utmp;
|
||||
|
||||
@@ -34,10 +34,18 @@
|
||||
# include <utmpx.h>
|
||||
# define UTMP_STRUCT_NAME utmpx
|
||||
# define UT_TIME_MEMBER(UT_PTR) ((UT_PTR)->ut_tv.tv_sec)
|
||||
# define SET_UTMP_ENT setutxent
|
||||
# define GET_UTMP_ENT getutxent
|
||||
# define END_UTMP_ENT endutxent
|
||||
# define UTMP_NAME_FUNCTION utmpxname
|
||||
# else
|
||||
# include <utmp.h>
|
||||
# define UTMP_STRUCT_NAME utmp
|
||||
# define UT_TIME_MEMBER(UT_PTR) ((UT_PTR)->ut_time)
|
||||
# define SET_UTMP_ENT setutent
|
||||
# define GET_UTMP_ENT getutent
|
||||
# define END_UTMP_ENT endutent
|
||||
# define UTMP_NAME_FUNCTION utmpname
|
||||
# endif
|
||||
|
||||
typedef struct UTMP_STRUCT_NAME STRUCT_UTMP;
|
||||
|
||||
31
lib/strtol.c
31
lib/strtol.c
@@ -1,5 +1,5 @@
|
||||
/* Convert string representation of a number into an integer value.
|
||||
Copyright (C) 1991, 92, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 92, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
NOTE: The canonical source of this file is maintained with the GNU C
|
||||
Library. Bugs can be reported to bug-glibc@gnu.org.
|
||||
|
||||
@@ -131,6 +131,31 @@ extern int errno;
|
||||
# define STRTOL_LONG_MIN LONG_LONG_MIN
|
||||
# define STRTOL_LONG_MAX LONG_LONG_MAX
|
||||
# define STRTOL_ULONG_MAX ULONG_LONG_MAX
|
||||
|
||||
/* The extra casts work around common compiler bugs,
|
||||
e.g. Cray C 5.0.3.0 when t == time_t. */
|
||||
# ifndef TYPE_SIGNED
|
||||
# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
||||
# endif
|
||||
# ifndef TYPE_MINIMUM
|
||||
# define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
|
||||
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
|
||||
: (t) 0))
|
||||
# endif
|
||||
# ifndef TYPE_MAXIMUM
|
||||
# define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
|
||||
# endif
|
||||
|
||||
# ifndef ULONG_LONG_MAX
|
||||
# define ULONG_LONG_MAX TYPE_MAXIMUM (unsigned long long)
|
||||
# endif
|
||||
# ifndef LONG_LONG_MAX
|
||||
# define LONG_LONG_MAX TYPE_MAXIMUM (long long int)
|
||||
# endif
|
||||
# ifndef LONG_LONG_MIN
|
||||
# define LONG_LONG_MIN TYPE_MINIMUM (long long int)
|
||||
# endif
|
||||
|
||||
# if __GNUC__ == 2 && __GNUC_MINOR__ < 7
|
||||
/* Work around gcc bug with using this constant. */
|
||||
static const unsigned long long int maxquad = ULONG_LONG_MAX;
|
||||
@@ -205,7 +230,9 @@ extern int errno;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
/* For compilers which are ansi but don't define __STDC__, like SGI
|
||||
Irix-4.0.5 cc, also check whether PROTOTYPES is defined. */
|
||||
#if defined (__STDC__) || defined (PROTOTYPES)
|
||||
# define INTERNAL(X) INTERNAL1(X)
|
||||
# define INTERNAL1(X) __##X##_internal
|
||||
# define WEAKNAME(X) WEAKNAME1(X)
|
||||
|
||||
@@ -54,7 +54,7 @@ utime_null (const char *file)
|
||||
int status = 0;
|
||||
struct stat sb;
|
||||
|
||||
fd = open (file, O_RDWR, 0666);
|
||||
fd = open (file, O_RDWR);
|
||||
if (fd < 0
|
||||
|| fstat (fd, &sb) < 0
|
||||
|| safe_read (fd, &c, sizeof (char)) < 0
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
1999-05-04 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* lfs.m4 (AC_LFS): -n32, -o32, and -n64 should be in CFLAGS,
|
||||
not CPPFLAGS, so that linking works correctly in IRIX.
|
||||
|
||||
1999-04-30 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* jm-macros.m4 (AC_REPLACE_FUNCS): Add dup2.
|
||||
|
||||
1999-04-20 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* xstrtoumax.m4: Require jm_AC_TYPE_UNSIGNED_LONG_LONG.
|
||||
|
||||
@@ -67,7 +67,6 @@ CC = @CC@
|
||||
CPP = @CPP@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
GENCAT = @GENCAT@
|
||||
GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
|
||||
GETCONF = @GETCONF@
|
||||
GMOFILES = @GMOFILES@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
@@ -79,11 +78,8 @@ INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLDEPS = @INTLDEPS@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLOBJS = @INTLOBJS@
|
||||
KMEM_GROUP = @KMEM_GROUP@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIB_CRYPT = @LIB_CRYPT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MAN = @MAN@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
MSGFMT = @MSGFMT@
|
||||
PACKAGE = @PACKAGE@
|
||||
@@ -92,8 +88,6 @@ 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@
|
||||
|
||||
@@ -39,6 +39,7 @@ AC_DEFUN(jm_MACROS,
|
||||
AC_REQUIRE([jm_AFS])
|
||||
AC_REQUIRE([jm_AC_PREREQ_XSTRTOUMAX])
|
||||
AC_REPLACE_FUNCS(strcasecmp strncasecmp)
|
||||
AC_REPLACE_FUNCS(dup2)
|
||||
|
||||
# By default, argmatch should fail calling usage (1).
|
||||
AC_DEFINE(ARGMATCH_DIE, [usage (1)],
|
||||
|
||||
@@ -73,7 +73,7 @@ AC_DEFUN(AC_LFS,
|
||||
-D_FILE_OFFSET_BITS=*) ;;
|
||||
-D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;;
|
||||
-D_LARGE_FILES | -D_LARGE_FILES=*) ;;
|
||||
-[[DI]]?* | -[[no]]32 | -n64)
|
||||
-[[DI]]?*)
|
||||
AC_LFS_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;;
|
||||
*)
|
||||
AC_LFS_SPACE_APPEND(CFLAGS, "$ac_flag") ;;
|
||||
|
||||
@@ -1,3 +1,156 @@
|
||||
1999-05-07 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* Version 4.0h.
|
||||
|
||||
* tests/touch/dir-1: New test.
|
||||
* tests/touch/Makefile.am (TESTS_ENVIRONMENT): Remove individual
|
||||
upper-case program names. Add a definition of PATH.
|
||||
(TESTS): Add dir-1.
|
||||
|
||||
* src/mkdir.c (main): Use better wording in diagnostic: `cannot
|
||||
create directory' rather than `cannot make directory'. The former
|
||||
also matches the one in makepath.c.
|
||||
|
||||
* src/dd.c: (apply_translations): Use TOUPPER and TOLOWER,
|
||||
not toupper and tolower.
|
||||
|
||||
1999-05-05 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* lib/makepath.c (make_dir): When reporting a mkdir failure and the
|
||||
target cannot be `stat'ed, use the errno from the failed mkdir call,
|
||||
not the one from the stat call. Before this change, running
|
||||
`mkdir -p /no-dir/no-dir' as an unprivileged user would wrongly
|
||||
elicit `No such file or directory' instead of `Permission denied'.
|
||||
|
||||
* lib/strtol.c (TYPE_SIGNED, TYPE_MAXIMUM, TYPE_MINIMUM): Define.
|
||||
(ULONG_LONG_MAX, LONG_LONG_MAX, LONG_LONG_MIN): Define if not defined.
|
||||
Based on a patch from Kaveh Ghazi.
|
||||
|
||||
* src/ls.c (USE_ACL): Define this only #if
|
||||
(HAVE_SYS_ACL_H && HAVE_ACL && defined GETACLCNT).
|
||||
Use `USE_ACL' in place of `HAVE_ACL' everywhere else. From Kaveh Ghazi.
|
||||
|
||||
1999-05-04 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* lib/makepath.c: Include makepath.h libintl.h, not after it.
|
||||
Otherwise, we'd get the wrong definition of PARAMS from libintl.h.
|
||||
(The method of defining PARAMS in libintl.h doesn't check PROTOTYPES,
|
||||
which is necessary on Irix4 since cc doesn't define __STDC__.)
|
||||
From Kaveh Ghazi.
|
||||
|
||||
1999-04-30 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* Makefile.maint: Define several tag-related make variables.
|
||||
(cvs-dist): Use the make variables instead of shell ones.
|
||||
(announcement): Automatically generate diffs for all ChangeLog files,
|
||||
not just the top level one.
|
||||
|
||||
1999-04-30 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* lib/dup2.c: New file.
|
||||
|
||||
1999-04-30 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* src/touch.c (touch): Only do the fstat if we need to.
|
||||
Resort to calling stat for directories, but only when necessary.
|
||||
(usage): Mention --no-create.
|
||||
|
||||
* src/copy.c (copy_internal): Move the one-file-system test so that
|
||||
it follows the `if (new_dst || !S_ISDIR (dst_sb.st_mode))' block.
|
||||
Prior to this change, `cp --one-file-system' would traverse a file-
|
||||
system boundary if the destination directory existed. From Ton Hospel.
|
||||
|
||||
1999-04-27 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* src/dd.c: Always use STDIN_FILENO for input and STDOUT_FILENO
|
||||
for output, to avoid confusion with closed input and output fds.
|
||||
(input_fd, output_fd): Remove; all uses changed to STDIN_FILENO
|
||||
and STDOUT_FILENO.
|
||||
(open_fd): New function.
|
||||
(main): Use it, instead of open, to ensure that file descriptors
|
||||
don't get confused.
|
||||
|
||||
1999-04-26 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* src/ls.c (decode_switches): Use STDIN_FILENO, STDOUT_FILENO instead
|
||||
of 0, 1.
|
||||
|
||||
* src/dd.c (skip): Don't fstat the input file; the result is
|
||||
no longer used.
|
||||
|
||||
1999-04-26 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* tests/mv/into-self-2: Update to reflect this change by reversing
|
||||
the order of arguments so the symlink is the source, not the
|
||||
destination (otherwise, the mv command would now succeed).
|
||||
|
||||
* src/copy.c (copy_internal): Don't make `mv foo symlink-to-foo' fail.
|
||||
That is, even though source and destination are `the same,' don't fail
|
||||
if the destination is a symlink. From Peter Samuelson.
|
||||
|
||||
1999-04-26 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* src/dd.c (main): If you can't open an output file (with
|
||||
seek=...) read-write, then open it for write and report an
|
||||
error if we can't seek.
|
||||
|
||||
* lib/filemode.c (setst, ftypelet, mode_string):
|
||||
* lib/mkdir.c (mkdir):
|
||||
* lib/makepath.c (make_path):
|
||||
* lib/modechange.c (make_node_op_equals, mode_compile,
|
||||
mode_create_from_ref, mode_adjust):
|
||||
* lib/modechange.h (mode_adjust):
|
||||
* src/chmod.c (describe_change, change_file_mode):
|
||||
* src/copy.c (copy_reg, copy_internal):
|
||||
* src/copy.h (struct cp_options.umask_kill):
|
||||
* src/cp.c (do_copy, cp_option_init, main):
|
||||
* src/dd.c (main):
|
||||
* src/install.c (mode, cp_option_init, DIR_MODE):
|
||||
* src/mkdir.c (main):
|
||||
* src/mkfifo.c (main):
|
||||
* src/mknod.c (main):
|
||||
* src/mv.c (cp_option_init):
|
||||
* src/touch.c (open_maybe_create):
|
||||
Use proper mode_t types and macros.
|
||||
Don't assume the traditional Unix values for mode bits.
|
||||
|
||||
* lib/filemode.c (S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH,
|
||||
S_IXOTH): Define if not defined.
|
||||
(rwx): Remove.
|
||||
* lib/mkdir.c (S_IRWXU, S_IRWXG, S_IRWXO): Define if not defined.
|
||||
* lib/makepath.c (S_ISUID, S_ISGID, S_ISVTX, S_IRUSR, S_IRWXU):
|
||||
Define if not defined.
|
||||
* src/system.h (S_ISUID, S_ISGID, S_ISVTX, S_IRWXU, S_IRWXG, S_IRWXO):
|
||||
Define if not defined.
|
||||
(CHMOD_MODE_BITS): New macro.
|
||||
* src/install.c (isodigit): Remove unused macro.
|
||||
|
||||
* src/mkfifo.c, src/mknod.c (usage):
|
||||
Use symbolic mode as default, not octal.
|
||||
|
||||
* lib/utime.c (utime_null):
|
||||
Don't pass 0666 to open; it's not needed and isn't
|
||||
guaranteed to be portable.
|
||||
|
||||
* lib/filemode.h: <config.h>, <sys/types.h>: Include for mode_t.
|
||||
(mode_string): Now takes mode_t.
|
||||
|
||||
* lib/modechange.h: Include <config.h>, <sys/types.h> for mode_t.
|
||||
(struct mode_change): Members affected and value are now mode_t instead
|
||||
of unsigned short.
|
||||
|
||||
* doc/fileutils.texi, doc/perm.texi:
|
||||
Don't assume traditional Unix mode numbering.
|
||||
|
||||
* lib/modechange.c: modechange.h now includes sys/types.h.
|
||||
Include xstrtol.h.
|
||||
(isodigit, oatoi): Remove.
|
||||
(S_ISUID, S_ISGID, S_ISVTX, S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP,
|
||||
S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH, S_IRWXU, S_IRWXG,
|
||||
S_IRWXO): Define if not defined.
|
||||
(CHMOD_MODE_BITS): New macro.
|
||||
(mode_compile): Convert from octal with xstrtoul, not our own routine.
|
||||
|
||||
1999-04-24 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* Version 4.0g.
|
||||
@@ -5,7 +158,7 @@
|
||||
1999-04-22 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* src/shred.c (word32): Don't use `#error'; it runs afoul of
|
||||
SunOS 4.1.4 cc.
|
||||
SunOS 4.1.4 cc. From Paul Eggert.
|
||||
|
||||
* lib/strtoull.c: Guard strong_alias and weak_alias with #ifdef _LIBC.
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
Changes in release 4.1:
|
||||
[4.0h]
|
||||
* cp --one-file-system (-x) no longer crosses filesystem boundaries.
|
||||
* touch can once again operate on directories
|
||||
[4.0g]
|
||||
* New large-file support for AIX and HP-UX, and for cross-compiles.
|
||||
* shred's default options are now suitable for devices, not files, since
|
||||
|
||||
@@ -1,5 +1,67 @@
|
||||
1999-05-09 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* Version 1.16i.
|
||||
|
||||
* configure.in: Clean up checks for libraries so that we don't add
|
||||
-lshadow unless necessary. Reported by Joseph S. Myers.
|
||||
|
||||
1999-05-05 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
Add definitions to help read utmpx on systems with utmpname.
|
||||
* lib/readutmp.h (UTMP_NAME_FUNCTION): Define.
|
||||
(SET_UTMP_ENT): Likewise.
|
||||
(GET_UTMP_ENT): Likewise.
|
||||
(END_UTMP_ENT): Likewise.
|
||||
* lib/readutmp.c (read_utmp): Use the new definitions.
|
||||
From Kaveh Ghazi.
|
||||
|
||||
* src/date.c (show_date): Change an automatic aggregate initializer
|
||||
to be a static one. For SunOS4's cc. From Kaveh Ghazi.
|
||||
|
||||
1999-05-03 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* configure.in: Remove duplicate use of jm_FUNC_GNU_STRFTIME.
|
||||
Kaveh Ghazi reported that strftime.o was listed twice in the command
|
||||
to build libsu.a.
|
||||
|
||||
1999-05-02 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* Version 1.16h.
|
||||
|
||||
* src/hostname.c (main): Give a better diagnostic when we fail to
|
||||
set the hostname.
|
||||
|
||||
* man/Makefile.summ (hostid-summary): Use correct description.
|
||||
Reported by Joseph S. Myers.
|
||||
|
||||
* lib/readutmp.c (read_utmp): Ignore the return value from utmpname.
|
||||
|
||||
1999-04-30 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* src/dirname.c (main): Manually handle `--', since we no longer
|
||||
call getopt. Reported by Joseph S. Myers.
|
||||
* src/basename.c (main): Likewise.
|
||||
* src/factor.c (main): Likewise.
|
||||
|
||||
1999-04-25 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* src/seq.c (main): Handle the case in which seq is given no args.
|
||||
Reported by John Gotts.
|
||||
(main): Revert last change.
|
||||
Instead, loop on `optind < argc' to protect use of argv[optind].
|
||||
|
||||
* lib/human.c <inttypes.h>: Don't include it here.
|
||||
* lib/human.h <inttypes.h>: Include it here instead.
|
||||
<config.h>: Include it here too.
|
||||
Reported by Andreas Jaeger.
|
||||
|
||||
* src/nice.c [NDEBUG]: Remove definition.
|
||||
Reported by Andreas Jaeger.
|
||||
|
||||
1999-04-24 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* src/who.c (print_entry): Use `#if', not `#ifdef HAVE_UT_HOST'.
|
||||
|
||||
* Version 1.16g.
|
||||
|
||||
* configure.in: Use AC_CANONICAL_HOST.
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
Changes in release 1.17
|
||||
[1.16i]
|
||||
* portability tweaks for lib/readutmp.[ch] and src/date.c
|
||||
[1.16h]
|
||||
* seq with no arguments now elicits a useful diagnostic rather than a segfault
|
||||
* portability tweaks to work around utmpname differences
|
||||
* who works on Solaris
|
||||
[1.16g]
|
||||
* factor now uses uintmax_t, so the largest number it can factor is now 2^64 - 1
|
||||
|
||||
@@ -1,3 +1,72 @@
|
||||
1999-05-09 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* Version 1.22k.
|
||||
|
||||
* Makefile.maint (alpha): Put the announcement in
|
||||
/tmp/announce-$(distdir)
|
||||
|
||||
* tests/sort/Test.pm (neg-nls): New test.
|
||||
|
||||
1999-05-08 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* src/system.h (CHAR_BIT, TYPE_SIGNED, TYPE_MINIMUM, TYPE_MAXIMUM,
|
||||
and all the *_MIN and *_MAX symbols): Remove definitions.
|
||||
* src/sys2.h: Put the definitions here instead (this file is shared
|
||||
between all three *utils packages, while system.h is not).
|
||||
|
||||
1999-05-06 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* src/sort.c (fraccompare, numcompare): Merge the NLS and
|
||||
non-NLS versions into a single function.
|
||||
|
||||
(decimal_point): Now char, since we no longer convert to unsigned
|
||||
char.
|
||||
(th_sep): Now int, since we use a value out of char range to denote
|
||||
the absence of a thousands separator.
|
||||
(IS_THOUSANDS_SEP): New macro.
|
||||
(USE_NEW_FRAC_COMPARE): Remove.
|
||||
(nls_set_fraction): Arg is now char, not unsigned char.
|
||||
Set th_sep to CHAR_MAX + 1 if there is no thousands separator.
|
||||
(numcompare): Don't convert to unsigned char unless necessary.
|
||||
(main): Turn off decimal points and thousand separators if they
|
||||
are multibyte characters, as we don't support that yet.
|
||||
|
||||
1999-05-06 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* src/system.h (CHAR_MIN, CHAR_MAX): New macros.
|
||||
(SCHAR_MIN, SCHAR_MAX): Don't assume that char is signed.
|
||||
|
||||
1999-05-06 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* src/sort.c (numcompare): Handle comparison of two negative
|
||||
numbers correctly in the ENABLE_NLS case.
|
||||
|
||||
1999-05-04 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* src/pr.c (usage): Break the usage message into 3 pieces instead of
|
||||
only 2. The strings had grown to be longer than 2048, which evokes
|
||||
errors when compiling with Irix4's cc. Reported by Kaveh Ghazi.
|
||||
|
||||
* src/tsort.c (search_item): Use `1' instead of `+1'. The latter
|
||||
elicits a syntax error from SunOS4's cc. From Kaveh Ghazi.
|
||||
|
||||
1999-05-03 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* src/ptx.c <ctype.h>: Don't include.
|
||||
[!STDC_HEADERS]: Remove definitions of ctype macros.
|
||||
Convert e.g., isspace to ISSPACE to use definitions from sys2.h.
|
||||
Reported by Kaveh Ghazi.
|
||||
|
||||
* src/sys2.h (TOLOWER): Define.
|
||||
(TOUPPER): Define.
|
||||
* src/join.c (TOLOWER): Remove definition.
|
||||
* src/md5sum.c: (TOLOWER): Remove definition.
|
||||
|
||||
1999-04-30 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* src/sort.c (usage): Document the differences between the
|
||||
obsolescent, +POS1[-POS2] form, and the POSIX -k option.
|
||||
|
||||
1999-04-24 Jim Meyering <meyering@ascend.com>
|
||||
|
||||
* configure.in: Use AC_CANONICAL_HOST.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
Changes in release 1.23
|
||||
[1.22k]
|
||||
* `sort -n' works with negative numbers when configured/compiled
|
||||
with --enable-nls
|
||||
* head accepts byte and line counts of type uintmax_t (so up to 2^64 - 1)
|
||||
[1.22j]
|
||||
* tail: fix bug introduced in 1.22i
|
||||
|
||||
@@ -100,6 +100,13 @@ main (int argc, char **argv)
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
|
||||
AUTHORS, usage);
|
||||
/* The above handles --help and --version.
|
||||
Since there is no other invocation of getopt, handle `--' here. */
|
||||
if (argc > 1 && STREQ (argv[1], "--"))
|
||||
{
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
|
||||
if (argc == 1 || argc > 3)
|
||||
{
|
||||
|
||||
16
src/chmod.c
16
src/chmod.c
@@ -91,7 +91,7 @@ static struct option const long_options[] =
|
||||
CHANGED describes what (if anything) has happened. */
|
||||
|
||||
static void
|
||||
describe_change (const char *file, short unsigned int mode,
|
||||
describe_change (const char *file, mode_t mode,
|
||||
enum Change_status changed)
|
||||
{
|
||||
char perms[11]; /* "-rwxrwxrwx" ls-style modes. */
|
||||
@@ -102,18 +102,18 @@ describe_change (const char *file, short unsigned int mode,
|
||||
switch (changed)
|
||||
{
|
||||
case CH_SUCCEEDED:
|
||||
fmt = _("mode of %s changed to %04o (%s)\n");
|
||||
fmt = _("mode of %s changed to %04lo (%s)\n");
|
||||
break;
|
||||
case CH_FAILED:
|
||||
fmt = _("failed to change mode of %s to %04o (%s)\n");
|
||||
fmt = _("failed to change mode of %s to %04lo (%s)\n");
|
||||
break;
|
||||
case CH_NO_CHANGE_REQUESTED:
|
||||
fmt = _("mode of %s retained as %04o (%s)\n");
|
||||
fmt = _("mode of %s retained as %04lo (%s)\n");
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
printf (fmt, file, mode & 07777, &perms[1]);
|
||||
printf (fmt, file, (unsigned long) (mode & CHMOD_MODE_BITS), &perms[1]);
|
||||
}
|
||||
|
||||
/* Change the mode of FILE according to the list of operations CHANGES.
|
||||
@@ -126,7 +126,7 @@ change_file_mode (const char *file, const struct mode_change *changes,
|
||||
const int deref_symlink)
|
||||
{
|
||||
struct stat file_stats;
|
||||
unsigned short newmode;
|
||||
mode_t newmode;
|
||||
int errors = 0;
|
||||
|
||||
if (lstat (file, &file_stats))
|
||||
@@ -152,9 +152,9 @@ change_file_mode (const char *file, const struct mode_change *changes,
|
||||
|
||||
newmode = mode_adjust (file_stats.st_mode, changes);
|
||||
|
||||
if (newmode != (file_stats.st_mode & 07777))
|
||||
if (newmode != (file_stats.st_mode & CHMOD_MODE_BITS))
|
||||
{
|
||||
int fail = chmod (file, (int) newmode);
|
||||
int fail = chmod (file, newmode);
|
||||
|
||||
if (verbosity == V_high || (verbosity == V_changes_only && !fail))
|
||||
describe_change (file, newmode, (fail ? CH_FAILED : CH_SUCCEEDED));
|
||||
|
||||
21
src/copy.c
21
src/copy.c
@@ -195,7 +195,7 @@ copy_reg (const char *src_path, const char *dst_path,
|
||||
/* Create the new regular file with small permissions initially,
|
||||
to not create a security hole. */
|
||||
|
||||
dest_desc = open (dst_path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
dest_desc = open (dst_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||
if (dest_desc < 0)
|
||||
{
|
||||
error (0, errno, _("cannot create regular file `%s'"), dst_path);
|
||||
@@ -428,9 +428,8 @@ copy_internal (const char *src_path, const char *dst_path,
|
||||
&& ! x->force
|
||||
|
||||
/* Allow them to be the same (and don't set `same') if
|
||||
we're in move mode and they're both symlinks. */
|
||||
we're in move mode and the target is a symlink. */
|
||||
&& !(move_mode
|
||||
&& S_ISLNK (src_sb.st_mode)
|
||||
&& S_ISLNK (dst_sb.st_mode))
|
||||
|
||||
/* If we're making a backup, we'll detect the problem case in
|
||||
@@ -488,9 +487,9 @@ copy_internal (const char *src_path, const char *dst_path,
|
||||
if (euidaccess (dst_path, W_OK) != 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
_("%s: overwrite `%s', overriding mode %04o? "),
|
||||
_("%s: overwrite `%s', overriding mode %04lo? "),
|
||||
program_name, dst_path,
|
||||
(unsigned int) (dst_sb.st_mode & 07777));
|
||||
(unsigned long) (dst_sb.st_mode & CHMOD_MODE_BITS));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -558,7 +557,7 @@ copy_internal (const char *src_path, const char *dst_path,
|
||||
/* Temporarily change mode to allow overwriting. */
|
||||
if (euidaccess (dst_path, W_OK | X_OK) != 0)
|
||||
{
|
||||
if (chmod (dst_path, 0700))
|
||||
if (chmod (dst_path, S_IRWXU))
|
||||
{
|
||||
error (0, errno, "%s", dst_path);
|
||||
return 1;
|
||||
@@ -682,7 +681,7 @@ copy_internal (const char *src_path, const char *dst_path,
|
||||
/* Create the new directory writable and searchable, so
|
||||
we can create new entries in it. */
|
||||
|
||||
if (mkdir (dst_path, (src_mode & x->umask_kill) | 0700))
|
||||
if (mkdir (dst_path, (src_mode & x->umask_kill) | S_IRWXU))
|
||||
{
|
||||
error (0, errno, _("cannot create directory `%s'"), dst_path);
|
||||
goto un_backup;
|
||||
@@ -697,12 +696,12 @@ copy_internal (const char *src_path, const char *dst_path,
|
||||
|
||||
if (x->verbose)
|
||||
printf ("%s -> %s\n", src_path, dst_path);
|
||||
|
||||
/* Are we crossing a file system boundary? */
|
||||
if (x->one_file_system && device != 0 && device != src_sb.st_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Are we crossing a file system boundary? */
|
||||
if (x->one_file_system && device != 0 && device != src_sb.st_dev)
|
||||
return 0;
|
||||
|
||||
/* Copy the contents of the directory. */
|
||||
|
||||
if (copy_dir (src_path, dst_path, new_dst, &src_sb, dir, x,
|
||||
|
||||
@@ -99,7 +99,7 @@ struct cp_options
|
||||
int symbolic_link;
|
||||
|
||||
/* The bits to preserve in created files' modes. */
|
||||
unsigned int umask_kill;
|
||||
mode_t umask_kill;
|
||||
|
||||
/* If nonzero, do not copy a nondirectory that has an existing destination
|
||||
with the same or newer modification time. */
|
||||
|
||||
6
src/cp.c
6
src/cp.c
@@ -461,7 +461,7 @@ do_copy (int argc, char **argv, const struct cp_options *x)
|
||||
leading directories. */
|
||||
parent_exists = !make_path_private (dst_path,
|
||||
arg_in_concat - dst_path,
|
||||
0700,
|
||||
S_IRWXU,
|
||||
(x->verbose
|
||||
? "%s -> %s\n" : NULL),
|
||||
&attr_list, &new_dst,
|
||||
@@ -617,7 +617,7 @@ cp_option_init (struct cp_options *x)
|
||||
when using chmod. The creation mask is set to be liberal, so
|
||||
that created directories can be written, even if it would not
|
||||
have been allowed with the mask this process was started with. */
|
||||
x->umask_kill = 0777777 ^ umask (0);
|
||||
x->umask_kill = ~ umask (0);
|
||||
|
||||
x->update = 0;
|
||||
x->verbose = 0;
|
||||
@@ -759,7 +759,7 @@ main (int argc, char **argv)
|
||||
: none);
|
||||
|
||||
if (x.preserve_chmod_bits == 1)
|
||||
x.umask_kill = 0777777;
|
||||
x.umask_kill = ~ (mode_t) 0;
|
||||
|
||||
/* The key difference between -d (--no-dereference) and not is the version
|
||||
of `stat' to call. */
|
||||
|
||||
@@ -746,7 +746,7 @@ handle_line_error (const struct control *p, int repetition)
|
||||
{
|
||||
char buf[LONGEST_HUMAN_READABLE + 1];
|
||||
|
||||
fprintf (stderr, _("%s: `%d': line number out of range"),
|
||||
fprintf (stderr, _("%s: `%s': line number out of range"),
|
||||
program_name, human_readable (p->lines_required, buf, 1, 1));
|
||||
if (repetition)
|
||||
fprintf (stderr, _(" on repetition %d\n"), repetition);
|
||||
|
||||
@@ -477,12 +477,14 @@ show_date (const char *format, time_t when)
|
||||
char *out = NULL;
|
||||
size_t out_length = 0;
|
||||
/* ISO 8601 formats, in local and UTC. See below regarding %z */
|
||||
char *iso_format_string[5][2]={
|
||||
static char *iso_format_string[5][2] =
|
||||
{
|
||||
{"", ""},
|
||||
{"%Y-%m-%d", "%Y-%m-%d"},
|
||||
{"%Y-%m-%dT%H%z", "%Y-%m-%dT%HZ"},
|
||||
{"%Y-%m-%dT%H:%M%z", "%Y-%m-%dT%H:%MZ"},
|
||||
{"%Y-%m-%dT%H:%M:%S%z", "%Y-%m-%dT%H:%M:%SZ"}};
|
||||
{"%Y-%m-%dT%H:%M:%S%z", "%Y-%m-%dT%H:%M:%SZ"}
|
||||
};
|
||||
|
||||
tm = localtime (&when);
|
||||
|
||||
|
||||
89
src/dd.c
89
src/dd.c
@@ -77,15 +77,9 @@ char *program_name;
|
||||
/* The name of the input file, or NULL for the standard input. */
|
||||
static char *input_file = NULL;
|
||||
|
||||
/* The input file descriptor. */
|
||||
static int input_fd = 0;
|
||||
|
||||
/* The name of the output file, or NULL for the standard output. */
|
||||
static char *output_file = NULL;
|
||||
|
||||
/* The output file descriptor. */
|
||||
static int output_fd = 1;
|
||||
|
||||
/* The number of bytes in which atomic reads are done. */
|
||||
static size_t input_blocksize = 0;
|
||||
|
||||
@@ -366,9 +360,9 @@ static void
|
||||
cleanup (void)
|
||||
{
|
||||
print_stats ();
|
||||
if (close (input_fd) < 0)
|
||||
if (close (STDIN_FILENO) < 0)
|
||||
error (1, errno, "%s", input_file);
|
||||
if (close (output_fd) < 0)
|
||||
if (close (STDOUT_FILENO) < 0)
|
||||
error (1, errno, "%s", output_file);
|
||||
}
|
||||
|
||||
@@ -423,12 +417,34 @@ install_handler (int sig_num, RETSIGTYPE (*sig_handler) (int sig))
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Open a file to a particular file descriptor. This is like standard
|
||||
`open', except it always returns DESIRED_FD if successful. */
|
||||
static int
|
||||
open_fd (int desired_fd, char const *filename, int options, mode_t mode)
|
||||
{
|
||||
int fd;
|
||||
close (desired_fd);
|
||||
fd = open (filename, options, mode);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
if (fd != desired_fd)
|
||||
{
|
||||
if (dup2 (fd, desired_fd) != desired_fd)
|
||||
desired_fd = -1;
|
||||
if (close (fd) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return desired_fd;
|
||||
}
|
||||
|
||||
/* Write, then empty, the output buffer `obuf'. */
|
||||
|
||||
static void
|
||||
write_output (void)
|
||||
{
|
||||
int nwritten = full_write (output_fd, obuf, output_blocksize);
|
||||
int nwritten = full_write (STDOUT_FILENO, obuf, output_blocksize);
|
||||
if (nwritten != output_blocksize)
|
||||
{
|
||||
error (0, errno, "%s", output_file);
|
||||
@@ -611,14 +627,14 @@ only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sy
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
if (ISLOWER (trans_table[i]))
|
||||
trans_table[i] = toupper (trans_table[i]);
|
||||
trans_table[i] = TOUPPER (trans_table[i]);
|
||||
translation_needed = 1;
|
||||
}
|
||||
else if (conversions_mask & C_LCASE)
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
if (ISUPPER (trans_table[i]))
|
||||
trans_table[i] = tolower (trans_table[i]);
|
||||
trans_table[i] = TOLOWER (trans_table[i]);
|
||||
translation_needed = 1;
|
||||
}
|
||||
|
||||
@@ -701,19 +717,8 @@ static void
|
||||
skip (int fdesc, char *file, uintmax_t records, size_t blocksize,
|
||||
unsigned char *buf)
|
||||
{
|
||||
struct stat stats;
|
||||
off_t o;
|
||||
|
||||
/* Use fstat instead of checking for errno == ESPIPE because
|
||||
lseek doesn't work on some special files but doesn't return an
|
||||
error, either. */
|
||||
/* FIXME: can this really happen? What system? */
|
||||
if (fstat (fdesc, &stats))
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
quit (1);
|
||||
}
|
||||
|
||||
/* Try lseek and if an error indicates it was an inappropriate
|
||||
operation, fall back on using read. */
|
||||
o = records * blocksize;
|
||||
@@ -856,7 +861,7 @@ dd_copy (void)
|
||||
obuf = ibuf;
|
||||
|
||||
if (skip_records != 0)
|
||||
skip (input_fd, input_file, skip_records, input_blocksize, ibuf);
|
||||
skip (STDIN_FILENO, input_file, skip_records, input_blocksize, ibuf);
|
||||
|
||||
if (seek_record != 0)
|
||||
{
|
||||
@@ -867,7 +872,8 @@ dd_copy (void)
|
||||
0+0 records out
|
||||
*/
|
||||
|
||||
skip (output_fd, output_file, seek_record, output_blocksize, obuf);
|
||||
skip (STDOUT_FILENO, output_file, seek_record, output_blocksize,
|
||||
obuf);
|
||||
}
|
||||
|
||||
if (max_records == 0)
|
||||
@@ -884,7 +890,7 @@ dd_copy (void)
|
||||
if ((conversions_mask & C_SYNC) && (conversions_mask & C_NOERROR))
|
||||
memset ((char *) ibuf, 0, input_blocksize);
|
||||
|
||||
nread = safe_read (input_fd, ibuf, input_blocksize);
|
||||
nread = safe_read (STDIN_FILENO, ibuf, input_blocksize);
|
||||
|
||||
if (nread == 0)
|
||||
break; /* EOF. */
|
||||
@@ -896,7 +902,7 @@ dd_copy (void)
|
||||
{
|
||||
print_stats ();
|
||||
/* Seek past the bad block if possible. */
|
||||
lseek (input_fd, (off_t) input_blocksize, SEEK_CUR);
|
||||
lseek (STDIN_FILENO, (off_t) input_blocksize, SEEK_CUR);
|
||||
if (conversions_mask & C_SYNC)
|
||||
/* Replace the missing input with null bytes and
|
||||
proceed normally. */
|
||||
@@ -928,7 +934,7 @@ dd_copy (void)
|
||||
|
||||
if (ibuf == obuf) /* If not C_TWOBUFS. */
|
||||
{
|
||||
int nwritten = full_write (output_fd, obuf, nread);
|
||||
int nwritten = full_write (STDOUT_FILENO, obuf, nread);
|
||||
if (nwritten < 0)
|
||||
{
|
||||
error (0, errno, "%s", output_file);
|
||||
@@ -987,7 +993,7 @@ dd_copy (void)
|
||||
/* Write out the last block. */
|
||||
if (oc != 0)
|
||||
{
|
||||
int nwritten = full_write (output_fd, obuf, oc);
|
||||
int nwritten = full_write (STDOUT_FILENO, obuf, oc);
|
||||
if (nwritten > 0)
|
||||
w_partial++;
|
||||
if (nwritten < 0)
|
||||
@@ -1029,28 +1035,25 @@ main (int argc, char **argv)
|
||||
|
||||
if (input_file != NULL)
|
||||
{
|
||||
input_fd = open (input_file, O_RDONLY);
|
||||
if (input_fd < 0)
|
||||
if (open_fd (STDIN_FILENO, input_file, O_RDONLY, 0) < 0)
|
||||
error (1, errno, "%s", input_file);
|
||||
}
|
||||
else
|
||||
input_file = _("standard input");
|
||||
|
||||
if (input_fd == output_fd)
|
||||
error (1, 0, _("%s is closed"), (input_fd == 0
|
||||
? _("standard input")
|
||||
: _("standard output")));
|
||||
|
||||
if (output_file != NULL)
|
||||
{
|
||||
/* Open the output file with *read* access only if we might
|
||||
need to read to satisfy a `seek=' request. */
|
||||
int omode = (seek_record ? O_RDWR : O_WRONLY) | O_CREAT;
|
||||
mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
int opts
|
||||
= (O_CREAT
|
||||
| (seek_record || (conversions_mask & C_NOTRUNC) ? 0 : O_TRUNC));
|
||||
|
||||
if (seek_record == 0 && !(conversions_mask & C_NOTRUNC))
|
||||
omode |= O_TRUNC;
|
||||
output_fd = open (output_file, omode, 0666);
|
||||
if (output_fd < 0)
|
||||
/* Open the output file with *read* access only if we might
|
||||
need to read to satisfy a `seek=' request. If we can't read
|
||||
the file, go ahead with write-only access; it might work. */
|
||||
if ((! seek_record
|
||||
|| open_fd (STDOUT_FILENO, output_file, O_RDWR | opts, perms) < 0)
|
||||
&& open_fd (STDOUT_FILENO, output_file, O_WRONLY | opts, perms) < 0)
|
||||
error (1, errno, "%s", output_file);
|
||||
#if HAVE_FTRUNCATE
|
||||
if (seek_record != 0 && !(conversions_mask & C_NOTRUNC))
|
||||
@@ -1058,7 +1061,7 @@ main (int argc, char **argv)
|
||||
off_t o = seek_record * output_blocksize;
|
||||
if (o / output_blocksize != seek_record)
|
||||
error (1, 0, _("file offset out of range"));
|
||||
if (ftruncate (output_fd, o) < 0)
|
||||
if (ftruncate (STDOUT_FILENO, o) < 0)
|
||||
error (0, errno, "%s", output_file);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -73,6 +73,13 @@ main (int argc, char **argv)
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
|
||||
AUTHORS, usage);
|
||||
/* The above handles --help and --version.
|
||||
Since there is no other invocation of getopt, handle `--' here. */
|
||||
if (argc > 1 && STREQ (argv[1], "--"))
|
||||
{
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
|
||||
@@ -183,6 +183,13 @@ main (int argc, char **argv)
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
|
||||
AUTHORS, usage);
|
||||
/* The above handles --help and --version.
|
||||
Since there is no other invocation of getopt, handle `--' here. */
|
||||
if (argc > 1 && STREQ (argv[1], "--"))
|
||||
{
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
|
||||
fail = 0;
|
||||
if (argc == 1)
|
||||
|
||||
@@ -98,7 +98,7 @@ main (int argc, char **argv)
|
||||
/* Set hostname to argv[1]. */
|
||||
err = sethostname (argv[1], strlen (argv[1]));
|
||||
if (err != 0)
|
||||
error (1, errno, "%s", argv[1]);
|
||||
error (1, errno, _("cannot set hostname to `%s'"), argv[1]);
|
||||
exit (0);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
-m, --mode=MODE
|
||||
Set the permission mode for the installed file or directory
|
||||
to MODE, which is an octal number (default is 0755).
|
||||
to MODE, which is an octal number (default is u=rwx,g=rx,o=rx).
|
||||
|
||||
-o, --owner=OWNER
|
||||
If run as root, set the ownership of the installed file to
|
||||
@@ -117,9 +117,6 @@ gid_t getgid ();
|
||||
/* Initial number of entries in the inode hash table. */
|
||||
#define INITIAL_ENTRY_TAB_SIZE 70
|
||||
|
||||
/* True if C is an ASCII octal digit. */
|
||||
#define isodigit(c) ((c) >= '0' && c <= '7')
|
||||
|
||||
/* Number of bytes of a file to copy at a time. */
|
||||
#define READ_SIZE (32 * 1024)
|
||||
|
||||
@@ -161,7 +158,7 @@ static gid_t group_id;
|
||||
|
||||
/* The permissions to which the files will be set. The umask has
|
||||
no effect. */
|
||||
static mode_t mode = 0755;
|
||||
static mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||
|
||||
/* If nonzero, strip executable files after copying them. */
|
||||
static int strip_files;
|
||||
@@ -214,7 +211,7 @@ cp_option_init (struct cp_options *x)
|
||||
Although GNU strip works fine on read-only files, some others
|
||||
would fail. */
|
||||
x->set_mode = 1;
|
||||
x->mode = 0600;
|
||||
x->mode = S_IRUSR | S_IWUSR;
|
||||
|
||||
x->umask_kill = 0;
|
||||
x->update = 0;
|
||||
@@ -402,7 +399,7 @@ install_file_to_path (const char *from, const char *to,
|
||||
owner, group, and permissions for parent directories. Remember
|
||||
that this option is intended mainly to help installers when the
|
||||
distribution doesn't provide proper install rules. */
|
||||
#define DIR_MODE 0755
|
||||
#define DIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
|
||||
fail = make_path (dest_dir, DIR_MODE, DIR_MODE, owner_id, group_id, 0,
|
||||
(x->verbose ? _("creating directory `%s'") : NULL));
|
||||
|
||||
|
||||
@@ -24,12 +24,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#if _LIBC || STDC_HEADERS
|
||||
# define TOLOWER(c) tolower (c)
|
||||
#else
|
||||
# define TOLOWER(c) (ISUPPER (c) ? tolower (c) : (c))
|
||||
#endif
|
||||
|
||||
#include "system.h"
|
||||
#include "error.h"
|
||||
#include "memcasecmp.h"
|
||||
|
||||
19
src/ls.c
19
src/ls.c
@@ -84,6 +84,13 @@
|
||||
#include "strverscmp.h"
|
||||
#include "xstrtol.h"
|
||||
|
||||
/* Use access control lists only under all the following conditions.
|
||||
Some systems (OSF4, Irix5, Irix6) have the acl function, but not
|
||||
sys/acl.h or don't define the GETACLCNT macro. */
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL && defined GETACLCNT
|
||||
# define USE_ACL 1
|
||||
#endif
|
||||
|
||||
#define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
|
||||
: (ls_mode == LS_MULTI_COL \
|
||||
? "dir" : "vdir"))
|
||||
@@ -164,14 +171,14 @@ struct fileinfo
|
||||
|
||||
enum filetype filetype;
|
||||
|
||||
#if HAVE_ACL
|
||||
#if USE_ACL
|
||||
/* For long listings, nonzero if the file has an access control list,
|
||||
otherwise zero. */
|
||||
int have_acl;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if HAVE_ACL
|
||||
#if USE_ACL
|
||||
# define FILE_HAS_ACL(F) ((F)->have_acl)
|
||||
#else
|
||||
# define FILE_HAS_ACL(F) 0
|
||||
@@ -872,7 +879,7 @@ decode_switches (int argc, char **argv)
|
||||
|
||||
case LS_LS:
|
||||
/* This is for the `ls' program. */
|
||||
if (isatty (1))
|
||||
if (isatty (STDOUT_FILENO))
|
||||
{
|
||||
format = many_per_line;
|
||||
/* See description of qmark_funny_chars, above. */
|
||||
@@ -931,7 +938,7 @@ decode_switches (int argc, char **argv)
|
||||
{
|
||||
struct winsize ws;
|
||||
|
||||
if (ioctl (1, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 0)
|
||||
if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 0)
|
||||
line_length = ws.ws_col;
|
||||
}
|
||||
#endif
|
||||
@@ -988,7 +995,7 @@ decode_switches (int argc, char **argv)
|
||||
sort_type = sort_none;
|
||||
/* disable -l */
|
||||
if (format == long_format)
|
||||
format = (isatty (1) ? many_per_line : one_per_line);
|
||||
format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
|
||||
print_block_size = 0; /* disable -s */
|
||||
print_with_color = 0; /* disable --color */
|
||||
break;
|
||||
@@ -1745,7 +1752,7 @@ gobble_file (const char *name, int explicit_arg, const char *dirname)
|
||||
else
|
||||
{
|
||||
val = lstat (path, &files[files_index].stat);
|
||||
#if HAVE_ACL
|
||||
#if USE_ACL
|
||||
files[files_index].have_acl = (acl (path, GETACLCNT, 0, NULL) > 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -59,12 +59,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if _LIBC || STDC_HEADERS
|
||||
# define TOLOWER(c) tolower (c)
|
||||
#else
|
||||
# define TOLOWER(c) (ISUPPER (c) ? tolower (c) : (c))
|
||||
#endif
|
||||
|
||||
/* The minimum length of a valid digest line in a file produced
|
||||
by `md5sum FILE' and read by `md5sum --check'. This length does
|
||||
not include any newline character at the end of a line. */
|
||||
|
||||
10
src/mkdir.c
10
src/mkdir.c
@@ -75,8 +75,8 @@ Create the DIRECTORY(ies), if they do not already exist.\n\
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
unsigned int newmode;
|
||||
unsigned int parent_mode;
|
||||
mode_t newmode;
|
||||
mode_t parent_mode;
|
||||
const char *symbolic_mode = NULL;
|
||||
const char *verbose_fmt_string = NULL;
|
||||
int errors = 0;
|
||||
@@ -117,8 +117,8 @@ main (int argc, char **argv)
|
||||
usage (1);
|
||||
}
|
||||
|
||||
newmode = 0777 & ~umask (0);
|
||||
parent_mode = newmode | 0300; /* u+wx */
|
||||
newmode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~ umask (0);
|
||||
parent_mode = S_IWUSR | S_IXUSR | newmode;
|
||||
if (symbolic_mode)
|
||||
{
|
||||
struct mode_change *change = mode_compile (symbolic_mode, 0);
|
||||
@@ -138,7 +138,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
else if (mkdir (argv[optind], newmode))
|
||||
{
|
||||
error (0, errno, _("cannot make directory `%s'"), argv[optind]);
|
||||
error (0, errno, _("cannot create directory `%s'"), argv[optind]);
|
||||
errors = 1;
|
||||
}
|
||||
else if (verbose_fmt_string)
|
||||
|
||||
@@ -60,7 +60,7 @@ usage (int status)
|
||||
printf (_("\
|
||||
Create named pipes (FIFOs) with the given NAMEs.\n\
|
||||
\n\
|
||||
-m, --mode=MODE set permission mode (as in chmod), not 0666 - umask\n\
|
||||
-m, --mode=MODE set permission mode (as in chmod), not a=rw - umask\n\
|
||||
--help display this help and exit\n\
|
||||
--version output version information and exit\n\
|
||||
"));
|
||||
@@ -74,7 +74,7 @@ Create named pipes (FIFOs) with the given NAMEs.\n\
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
unsigned short newmode;
|
||||
mode_t newmode;
|
||||
struct mode_change *change;
|
||||
const char *symbolic_mode;
|
||||
int errors = 0;
|
||||
@@ -112,7 +112,8 @@ main (int argc, char **argv)
|
||||
usage (1);
|
||||
}
|
||||
|
||||
newmode = 0666 & ~umask (0);
|
||||
newmode = ((S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
|
||||
& ~ umask (0));
|
||||
if (symbolic_mode)
|
||||
{
|
||||
change = mode_compile (symbolic_mode, 0);
|
||||
|
||||
@@ -65,7 +65,7 @@ usage (int status)
|
||||
printf (_("\
|
||||
Create the special file NAME of the given TYPE.\n\
|
||||
\n\
|
||||
-m, --mode=MODE set permission mode (as in chmod), not 0666 - umask\n\
|
||||
-m, --mode=MODE set permission mode (as in chmod), not a=rw - umask\n\
|
||||
--help display this help and exit\n\
|
||||
--version output version information and exit\n\
|
||||
\n\
|
||||
@@ -84,7 +84,7 @@ MAJOR MINOR are forbidden for TYPE p, mandatory otherwise. TYPE may be:\n\
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
unsigned short newmode;
|
||||
mode_t newmode;
|
||||
struct mode_change *change;
|
||||
const char *symbolic_mode;
|
||||
int optc;
|
||||
@@ -115,7 +115,8 @@ main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
newmode = 0666 & ~umask (0);
|
||||
newmode = ((S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
|
||||
& ~ umask (0));
|
||||
if (symbolic_mode)
|
||||
{
|
||||
change = mode_compile (symbolic_mode, 0);
|
||||
|
||||
2
src/mv.c
2
src/mv.c
@@ -136,7 +136,7 @@ cp_option_init (struct cp_options *x)
|
||||
when using chmod. The creation mask is set to be liberal, so
|
||||
that created directories can be written, even if it would not
|
||||
have been allowed with the mask this process was started with. */
|
||||
x->umask_kill = 0777777 ^ umask (0);
|
||||
x->umask_kill = ~ umask (0);
|
||||
|
||||
x->update = 0;
|
||||
x->verbose = 0;
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
7
src/pr.c
7
src/pr.c
@@ -2805,6 +2805,8 @@ produce empty pages.\n\
|
||||
use form feeds instead of newlines to separate pages\n\
|
||||
(by a 3-line page header with -F or a 5-line header\n\
|
||||
and trailer without -F)\n\
|
||||
"));
|
||||
printf (_("\
|
||||
-h HEADER, --header=HEADER\n\
|
||||
use a centered HEADER instead of filename in page header,\n\
|
||||
with long headers left-hand-side truncation may occur,\n\
|
||||
@@ -2815,8 +2817,7 @@ produce empty pages.\n\
|
||||
alignment, -S[STRING] sets separators\n\
|
||||
-l PAGE_LENGTH, --length=PAGE_LENGTH\n\
|
||||
set the page length to PAGE_LENGTH (66) lines\n\
|
||||
(default number of lines of text 56, and with -F 63)\n"));
|
||||
printf (_("\
|
||||
(default number of lines of text 56, and with -F 63)\n\
|
||||
-m, --merge print all files in parallel, one in each column,\n\
|
||||
truncate lines, but join lines of full length with -J\n\
|
||||
-n[SEP[DIGITS]], --number-lines[=SEP[DIGITS]]\n\
|
||||
@@ -2830,6 +2831,8 @@ produce empty pages.\n\
|
||||
affect -w or -W, MARGIN will be added to PAGE_WIDTH\n\
|
||||
-r, --no-file-warnings\n\
|
||||
omit warning when a file cannot be opened\n\
|
||||
"));
|
||||
printf (_("\
|
||||
-s[CHAR],--separator[=CHAR]\n\
|
||||
separate columns by a single character, default for CHAR\n\
|
||||
is the <TAB> character without -w and \'no char\' with -w\n\
|
||||
|
||||
37
src/ptx.c
37
src/ptx.c
@@ -38,29 +38,6 @@
|
||||
/* Number of possible characters in a byte. */
|
||||
#define CHAR_SET_SIZE 256
|
||||
|
||||
/* The ctype definitions should work for all 256 characters. */
|
||||
#if STDC_HEADERS
|
||||
# include <ctype.h>
|
||||
#else
|
||||
# define isspace(C) ((C) == ' ' || (C) == '\t' || (C) == '\n')
|
||||
# define isxdigit(C) \
|
||||
(((unsigned char) (C) >= 'a' && (unsigned char) (C) <= 'f') \
|
||||
|| ((unsigned char) (C) >= 'A' && (unsigned char) (C) <= 'F') \
|
||||
|| ((unsigned char) (C) >= '0' && (unsigned char) (C) <= '9'))
|
||||
# define islower(C) ((unsigned char) (C) >= 'a' && (unsigned char) (C) <= 'z')
|
||||
# define isupper(C) ((unsigned char) (C) >= 'A' && (unsigned char) (C) <= 'Z')
|
||||
# define isalpha(C) (islower (C) || isupper (C))
|
||||
# define toupper(C) (islower (C) ? (C) - 'a' + 'A' : (C))
|
||||
#endif
|
||||
|
||||
#if !defined (isascii) || defined (STDC_HEADERS)
|
||||
# undef isascii
|
||||
# define isascii(C) 1
|
||||
#endif
|
||||
|
||||
#ifndef ISXDIGIT
|
||||
# define ISXDIGIT(C) (isascii (C) && isxdigit (C))
|
||||
#endif
|
||||
#define ISODIGIT(C) ((C) >= '0' && (C) <= '7')
|
||||
#define HEXTOBIN(C) ((C) >= 'a' && (C) <= 'f' ? (C)-'a'+10 \
|
||||
: (C) >= 'A' && (C) <= 'F' ? (C)-'A'+10 : (C)-'0')
|
||||
@@ -196,15 +173,15 @@ char *text_buffer_maxend; /* allocated end of text_buffer */
|
||||
/* SKIP_NON_WHITE used only for getting or skipping the reference. */
|
||||
|
||||
#define SKIP_NON_WHITE(cursor, limit) \
|
||||
while (cursor < limit && !isspace(*cursor)) \
|
||||
while (cursor < limit && !ISSPACE(*cursor)) \
|
||||
cursor++
|
||||
|
||||
#define SKIP_WHITE(cursor, limit) \
|
||||
while (cursor < limit && isspace(*cursor)) \
|
||||
while (cursor < limit && ISSPACE(*cursor)) \
|
||||
cursor++
|
||||
|
||||
#define SKIP_WHITE_BACKWARDS(cursor, start) \
|
||||
while (cursor > start && isspace(cursor[-1])) \
|
||||
while (cursor > start && ISSPACE(cursor[-1])) \
|
||||
cursor--
|
||||
|
||||
#define SKIP_SOMETHING(cursor, limit) \
|
||||
@@ -462,13 +439,13 @@ initialize_regex (void)
|
||||
/* Initialize the regex syntax table. */
|
||||
|
||||
for (character = 0; character < CHAR_SET_SIZE; character++)
|
||||
syntax_table[character] = isalpha (character) ? Sword : 0;
|
||||
syntax_table[character] = ISALPHA (character) ? Sword : 0;
|
||||
|
||||
/* Initialize the case folding table. */
|
||||
|
||||
if (ignore_case)
|
||||
for (character = 0; character < CHAR_SET_SIZE; character++)
|
||||
folded_chars[character] = toupper (character);
|
||||
folded_chars[character] = TOUPPER (character);
|
||||
|
||||
/* Unless the user already provided a description of the end of line or
|
||||
end of sentence sequence, select an end of line sequence to compile.
|
||||
@@ -508,7 +485,7 @@ initialize_regex (void)
|
||||
/* Simulate \w+. */
|
||||
|
||||
for (character = 0; character < CHAR_SET_SIZE; character++)
|
||||
word_fastmap[character] = isalpha (character) ? 1 : 0;
|
||||
word_fastmap[character] = ISALPHA (character) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1368,7 +1345,7 @@ fix_output_parameters (void)
|
||||
form feed as a space character, but we do. */
|
||||
|
||||
for (character = 0; character < CHAR_SET_SIZE; character++)
|
||||
edited_flag[character] = isspace (character) != 0;
|
||||
edited_flag[character] = ISSPACE (character) != 0;
|
||||
edited_flag['\f'] = 1;
|
||||
|
||||
/* Complete the special character flagging according to selected output
|
||||
|
||||
@@ -143,7 +143,7 @@ main (int argc, char **argv)
|
||||
/* We have to handle negative numbers in the command line but this
|
||||
conflicts with the command line arguments. So explicitly check first
|
||||
whether the next argument looks like a negative number. */
|
||||
while (1)
|
||||
while (optind < argc)
|
||||
{
|
||||
if (argv[optind][0] == '-'
|
||||
&& ((optc = argv[optind][1]) == decimal_point[0]
|
||||
|
||||
424
src/sort.c
424
src/sort.c
@@ -85,8 +85,8 @@ char *xstrdup ();
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
|
||||
static unsigned char decimal_point;
|
||||
static unsigned char th_sep;
|
||||
static char decimal_point;
|
||||
static int th_sep; /* if CHAR_MAX + 1, then there is no thousands separator */
|
||||
static char *nls_grouping;
|
||||
|
||||
/* This is "C" locale, need another? */
|
||||
@@ -98,9 +98,12 @@ static int nls_fraction_found = 1;
|
||||
/* Look for month notations in text? */
|
||||
static int nls_month_found = 1;
|
||||
|
||||
# define IS_THOUSANDS_SEP(x) ((x) == th_sep)
|
||||
|
||||
#else
|
||||
|
||||
# define decimal_point FLOATING_POINT
|
||||
# define IS_THOUSANDS_SEP(x) 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -289,14 +292,18 @@ Usage: %s [OPTION]... [FILE]...\n\
|
||||
printf (_("\
|
||||
Write sorted concatenation of all FILE(s) to standard output.\n\
|
||||
\n\
|
||||
+POS1 [-POS2] start a key at POS1, end it before POS2\n\
|
||||
+POS1 [-POS2] start a key at POS1, end it *before* POS2 (obsolescent)\n\
|
||||
field numbers and character offsets are numbered\n\
|
||||
starting with zero (contrast with the -k option)\n\
|
||||
-b ignore leading blanks in sort fields or keys\n\
|
||||
-c check if given files already sorted, do not sort\n\
|
||||
-d consider only [a-zA-Z0-9 ] characters in keys\n\
|
||||
-f fold lower case to upper case characters in keys\n\
|
||||
-g compare according to general numerical value, imply -b\n\
|
||||
-i consider only [\\040-\\0176] characters in keys\n\
|
||||
-k POS1[,POS2] same as +POS1 [-POS2], but all positions counted from 1\n\
|
||||
-k POS1[,POS2] start a key at POS1, end it *at* POS2\n\
|
||||
field numbers and character offsets are numbered\n\
|
||||
starting with one (contrast with zero-based +POS form)\n\
|
||||
-m merge already sorted files, do not sort\n\
|
||||
-M compare (unknown) < `JAN' < ... < `DEC', imply -b\n\
|
||||
-n compare according to string numerical value, imply -b\n\
|
||||
@@ -311,11 +318,11 @@ Write sorted concatenation of all FILE(s) to standard output.\n\
|
||||
--help display this help and exit\n\
|
||||
--version output version information and exit\n\
|
||||
\n\
|
||||
POS is F[.C][OPTS], where F is the field number and C the character\n\
|
||||
position in the field, both counted from zero. OPTS is made up of one\n\
|
||||
or more of Mbdfinr, this effectively disable global -Mbdfinr settings\n\
|
||||
for that key. If no key given, use the entire line as key. With no\n\
|
||||
FILE, or when FILE is -, read standard input.\n\
|
||||
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\
|
||||
")
|
||||
, DEFAULT_TMPDIR);
|
||||
puts (_("\nReport bugs to <bug-textutils@gnu.org>."));
|
||||
@@ -922,144 +929,56 @@ findlines (struct buffer *buf, struct lines *lines)
|
||||
find first character different in a and b.
|
||||
if both are digits, return the difference *a - *b.
|
||||
if *a is a digit
|
||||
skip past zeroes
|
||||
skip past zeros
|
||||
if digit return 1, else 0
|
||||
if *b is a digit
|
||||
skip past zeroes
|
||||
skip past zeros
|
||||
if digit return -1, else 0
|
||||
if *a is a decimal_point
|
||||
skip past decimal_point and zeroes
|
||||
skip past decimal_point and zeros
|
||||
if digit return 1, else 0
|
||||
if *b is a decimal_point
|
||||
skip past decimal_point and zeroes
|
||||
skip past decimal_point and zeros
|
||||
if digit return -1, else 0
|
||||
return 0
|
||||
|
||||
The above implementation duplicates code, and thus there is room
|
||||
for improvement:
|
||||
the difference in code of a and b, is solved by using a
|
||||
reference to s, assigned to either a or b. and using diff
|
||||
to denote return value.
|
||||
the difference in either that start being a digit or
|
||||
the decimal point, is solved by testing if either is
|
||||
a decimal point, or if the other is a digit...
|
||||
|
||||
if *a or *b is a decimal_point
|
||||
skip all chars where *a == *b
|
||||
if *a and *b are digits
|
||||
return *a - *b
|
||||
if *a is a digit or *a is a decimal_point
|
||||
s is a
|
||||
diff is 1
|
||||
else
|
||||
s is b
|
||||
diff is -1
|
||||
skip decimal_point in s
|
||||
skip zeroes in s
|
||||
if *s is a digit
|
||||
return diff
|
||||
return 0 */
|
||||
|
||||
#define USE_NEW_FRAC_COMPARE
|
||||
#ifdef USE_NEW_FRAC_COMPARE
|
||||
return 0 */
|
||||
|
||||
static int
|
||||
fraccompare (register const char *a, register const char *b)
|
||||
{
|
||||
# ifdef ENABLE_NLS
|
||||
#ifdef ENABLE_NLS
|
||||
nls_fraction_found = 1;
|
||||
# endif
|
||||
|
||||
if (*a == decimal_point || *b == decimal_point)
|
||||
{
|
||||
register const char *s;
|
||||
int diff;
|
||||
|
||||
while (*a == *b)
|
||||
{
|
||||
++a;
|
||||
++b;
|
||||
if (!ISDIGIT (*a))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ISDIGIT (*a) && ISDIGIT (*b))
|
||||
return (*a) - (*b);
|
||||
|
||||
if (*a == decimal_point || (ISDIGIT (*a) && *b != decimal_point))
|
||||
{
|
||||
s = a;
|
||||
diff = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = b;
|
||||
diff = -1;
|
||||
}
|
||||
if (*s == decimal_point)
|
||||
++s;
|
||||
while (*s == NUMERIC_ZERO)
|
||||
++s;
|
||||
if (ISDIGIT (*s))
|
||||
return diff;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
static int
|
||||
fraccompare (register const char *a, register const char *b)
|
||||
{
|
||||
register int tmpa = *a;
|
||||
register int tmpb = *b;
|
||||
|
||||
if (tmpa == decimal_point && tmpb == decimal_point)
|
||||
{
|
||||
do
|
||||
tmpa = *++a, tmpb = *++b;
|
||||
while (tmpa == tmpb && ISDIGIT (tmpa));
|
||||
if (ISDIGIT (tmpa) && ISDIGIT (tmpb))
|
||||
return tmpa - tmpb;
|
||||
if (ISDIGIT (tmpa))
|
||||
{
|
||||
while (tmpa == NUMERIC_ZERO)
|
||||
tmpa = *++a;
|
||||
if (ISDIGIT (tmpa))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
if (ISDIGIT (tmpb))
|
||||
{
|
||||
while (tmpb == NUMERIC_ZERO)
|
||||
tmpb = *++b;
|
||||
if (ISDIGIT (tmpb))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (tmpa == decimal_point)
|
||||
{
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == NUMERIC_ZERO);
|
||||
if (ISDIGIT (tmpa))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
else if (tmpb == decimal_point)
|
||||
{
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO);
|
||||
if (ISDIGIT (tmpb))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (*a == decimal_point && *b == decimal_point)
|
||||
{
|
||||
while (*++a == *++b)
|
||||
if (! ISDIGIT (*a))
|
||||
return 0;
|
||||
if (ISDIGIT (*a) && ISDIGIT (*b))
|
||||
return *a - *b;
|
||||
if (ISDIGIT (*a))
|
||||
goto a_trailing_nonzero;
|
||||
if (ISDIGIT (*b))
|
||||
goto b_trailing_nonzero;
|
||||
return 0;
|
||||
}
|
||||
else if (*a++ == decimal_point)
|
||||
{
|
||||
a_trailing_nonzero:
|
||||
while (*a == NUMERIC_ZERO)
|
||||
a++;
|
||||
return ISDIGIT (*a);
|
||||
}
|
||||
else if (*b++ == decimal_point)
|
||||
{
|
||||
b_trailing_nonzero:
|
||||
while (*b == NUMERIC_ZERO)
|
||||
b++;
|
||||
return - ISDIGIT (*b);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compare strings A and B as numbers without explicitly converting them to
|
||||
machine numbers. Comparatively slow for short strings, but asymptotically
|
||||
hideously fast. */
|
||||
@@ -1072,7 +991,7 @@ fraccompare (register const char *a, register const char *b)
|
||||
|
||||
/* Decide the kind of fraction the program will use */
|
||||
static void
|
||||
nls_set_fraction (register unsigned char ch)
|
||||
nls_set_fraction (char ch)
|
||||
{
|
||||
if (!nls_fraction_found && ch != decimal_point)
|
||||
{
|
||||
@@ -1089,7 +1008,7 @@ nls_set_fraction (register unsigned char ch)
|
||||
else if (ch != decimal_point)
|
||||
{ /* Alien */
|
||||
decimal_point = ch;
|
||||
th_sep = '\0';
|
||||
th_sep = CHAR_MAX + 1;
|
||||
}
|
||||
}
|
||||
nls_fraction_found = 1;
|
||||
@@ -1216,125 +1135,26 @@ look_for_fraction (const char *s, const char *e)
|
||||
nls_set_fraction (*s);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
numcompare (register const char *a, register const char *b)
|
||||
{
|
||||
int ret_code = 1; /* normal return status, see later in code */
|
||||
int diff = 0; /* difference between two digits */
|
||||
|
||||
while (blanks[UCHAR (*a)])
|
||||
++a;
|
||||
while (blanks[UCHAR (*b)])
|
||||
++b;
|
||||
|
||||
/* next character in a,b is non-blank */
|
||||
if ((*a == NEGATION_SIGN || *b == NEGATION_SIGN) && *a != *b)
|
||||
{
|
||||
/* a < 0, or b < 0, but not both */
|
||||
if (*a == NEGATION_SIGN)
|
||||
ret_code = -1, ++a; /* a looks < b */
|
||||
else if (*b == NEGATION_SIGN)
|
||||
ret_code = 1, ++b; /* b looks < a */
|
||||
/* bypass zeroes, decimal points, and thousand sep in a & b */
|
||||
while (*a == NUMERIC_ZERO || (th_sep && *a == th_sep)
|
||||
|| *a == decimal_point)
|
||||
++a;
|
||||
|
||||
while (*b == NUMERIC_ZERO || (th_sep && *b == th_sep)
|
||||
|| *b == decimal_point)
|
||||
++b;
|
||||
|
||||
if (ISDIGIT (*a) || ISDIGIT (*b))
|
||||
/* here, either a or b or both are digits
|
||||
if a and b are digits, the signed one is the lesser.
|
||||
if a is a digit, and not b.. it means b==0, and if b==0
|
||||
than either is signed if b is signed then -0 < a
|
||||
or if a is signed then -a < 0. The ret_code is already set
|
||||
to mark that the signed number is the lesser, so we just
|
||||
return that number here. */
|
||||
return ret_code;
|
||||
|
||||
/* *a and *b are neither digits, they are equal -0 == +0 */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* either both numbers are signed, or both are not-signed */
|
||||
if (*a == NEGATION_SIGN)
|
||||
{
|
||||
++a;
|
||||
++b;
|
||||
ret_code = -1;
|
||||
}
|
||||
/* if both are signed, then remember -100 < -10 (ret_code reversed!) */
|
||||
|
||||
/* Skip any leading zeroes */
|
||||
while (*a == NUMERIC_ZERO)
|
||||
++a;
|
||||
while (*b == NUMERIC_ZERO)
|
||||
++b;
|
||||
|
||||
continue_thousands:
|
||||
|
||||
/* skip all equal digits */
|
||||
while (ISDIGIT (*a) && ISDIGIT (*b) && *a == *b)
|
||||
a++, b++;
|
||||
|
||||
/* Here, we have either different digits, or possible fractions
|
||||
or thousand separators. */
|
||||
|
||||
if (ISDIGIT (*a) && ISDIGIT (*b))
|
||||
{
|
||||
if (diff == 0)
|
||||
diff = ((*a) - (*b)); /* simple, isn't it? not quite */
|
||||
a++, b++;
|
||||
goto continue_thousands;
|
||||
}
|
||||
|
||||
/* now, here either may be a fraction, or a thousand separator...
|
||||
or both. */
|
||||
/* We've decided what are decimal_points, and what are thousands sep */
|
||||
if ((th_sep != 0) && (*a == th_sep || *b == th_sep))
|
||||
{
|
||||
if (*a == th_sep)
|
||||
++a;
|
||||
if (*b == th_sep)
|
||||
++b;
|
||||
goto continue_thousands; /* Ugly, but better than a while(1) */
|
||||
}
|
||||
|
||||
if (ISDIGIT (*a))
|
||||
return ret_code; /* a has more digits than b */
|
||||
if (ISDIGIT (*b))
|
||||
return ret_code * -1; /* b has more digits than a */
|
||||
|
||||
/* now, we should have the fractions solved */
|
||||
if ((diff == 0) && (*a == decimal_point || *b == decimal_point))
|
||||
return ret_code * fraccompare (a, b);
|
||||
|
||||
return diff; /* fall through here, and diff decides */
|
||||
}
|
||||
}
|
||||
#else
|
||||
static int
|
||||
numcompare (register const char *a, register const char *b)
|
||||
{
|
||||
register int tmpa, tmpb, loga, logb, tmp;
|
||||
|
||||
tmpa = UCHAR (*a);
|
||||
tmpb = UCHAR (*b);
|
||||
tmpa = *a;
|
||||
tmpb = *b;
|
||||
|
||||
while (blanks[tmpa])
|
||||
tmpa = UCHAR (*++a);
|
||||
while (blanks[tmpb])
|
||||
tmpb = UCHAR (*++b);
|
||||
while (blanks[UCHAR (tmpa)])
|
||||
tmpa = *++a;
|
||||
while (blanks[UCHAR (tmpb)])
|
||||
tmpb = *++b;
|
||||
|
||||
if (tmpa == NEGATION_SIGN)
|
||||
{
|
||||
do
|
||||
tmpa = UCHAR (*++a);
|
||||
while (tmpa == NUMERIC_ZERO);
|
||||
tmpa = *++a;
|
||||
while (tmpa == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpa));
|
||||
if (tmpb != NEGATION_SIGN)
|
||||
{
|
||||
if (tmpa == decimal_point)
|
||||
@@ -1343,8 +1163,8 @@ numcompare (register const char *a, register const char *b)
|
||||
while (tmpa == NUMERIC_ZERO);
|
||||
if (ISDIGIT (tmpa))
|
||||
return -1;
|
||||
while (tmpb == NUMERIC_ZERO)
|
||||
tmpb = UCHAR (*++b);
|
||||
while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb))
|
||||
tmpb = *++b;
|
||||
if (tmpb == decimal_point)
|
||||
do
|
||||
tmpb = *++b;
|
||||
@@ -1354,52 +1174,59 @@ numcompare (register const char *a, register const char *b)
|
||||
return 0;
|
||||
}
|
||||
do
|
||||
tmpb = UCHAR (*++b);
|
||||
while (tmpb == NUMERIC_ZERO);
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb));
|
||||
|
||||
while (tmpa == tmpb && ISDIGIT (tmpa))
|
||||
tmpa = UCHAR (*++a), tmpb = UCHAR (*++b);
|
||||
{
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (IS_THOUSANDS_SEP (tmpa));
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (IS_THOUSANDS_SEP (tmpb));
|
||||
}
|
||||
|
||||
if ((tmpa == decimal_point && !ISDIGIT (tmpb))
|
||||
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
|
||||
return -fraccompare (a, b);
|
||||
|
||||
if (ISDIGIT (tmpa))
|
||||
for (loga = 1; ISDIGIT (UCHAR (*++a)); ++loga)
|
||||
;
|
||||
else
|
||||
loga = 0;
|
||||
tmp = tmpb - tmpa;
|
||||
|
||||
if (ISDIGIT (tmpb))
|
||||
for (logb = 1; ISDIGIT (UCHAR (*++b)); ++logb)
|
||||
;
|
||||
else
|
||||
logb = 0;
|
||||
for (loga = 0; ISDIGIT (tmpa); ++loga)
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (IS_THOUSANDS_SEP (tmpa));
|
||||
|
||||
if ((tmp = logb - loga) != 0)
|
||||
return tmp;
|
||||
for (logb = 0; ISDIGIT (tmpb); ++logb)
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (IS_THOUSANDS_SEP (tmpb));
|
||||
|
||||
if (logb - loga != 0)
|
||||
return logb - loga;
|
||||
|
||||
if (!loga)
|
||||
return 0;
|
||||
|
||||
return tmpb - tmpa;
|
||||
return tmp;
|
||||
}
|
||||
else if (tmpb == NEGATION_SIGN)
|
||||
{
|
||||
do
|
||||
tmpb = UCHAR (*++b);
|
||||
while (tmpb == NUMERIC_ZERO);
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb));
|
||||
if (tmpb == decimal_point)
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO);
|
||||
if (ISDIGIT (tmpb))
|
||||
return 1;
|
||||
while (tmpa == NUMERIC_ZERO)
|
||||
tmpa = UCHAR (*++a);
|
||||
while (tmpa == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpa))
|
||||
tmpa = *++a;
|
||||
if (tmpa == decimal_point)
|
||||
do
|
||||
tmpa = UCHAR (*++a);
|
||||
tmpa = *++a;
|
||||
while (tmpa == NUMERIC_ZERO);
|
||||
if (ISDIGIT (tmpa))
|
||||
return 1;
|
||||
@@ -1407,40 +1234,46 @@ numcompare (register const char *a, register const char *b)
|
||||
}
|
||||
else
|
||||
{
|
||||
while (tmpa == NUMERIC_ZERO)
|
||||
tmpa = UCHAR (*++a);
|
||||
while (tmpb == NUMERIC_ZERO)
|
||||
tmpb = UCHAR (*++b);
|
||||
while (tmpa == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpa))
|
||||
tmpa = *++a;
|
||||
while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb))
|
||||
tmpb = *++b;
|
||||
|
||||
while (tmpa == tmpb && ISDIGIT (tmpa))
|
||||
tmpa = UCHAR (*++a), tmpb = UCHAR (*++b);
|
||||
{
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (IS_THOUSANDS_SEP (tmpa));
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (IS_THOUSANDS_SEP (tmpb));
|
||||
}
|
||||
|
||||
if ((tmpa == decimal_point && !ISDIGIT (tmpb))
|
||||
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
|
||||
return fraccompare (a, b);
|
||||
|
||||
if (ISDIGIT (tmpa))
|
||||
for (loga = 1; ISDIGIT (UCHAR (*++a)); ++loga)
|
||||
;
|
||||
else
|
||||
loga = 0;
|
||||
tmp = tmpa - tmpb;
|
||||
|
||||
if (ISDIGIT (tmpb))
|
||||
for (logb = 1; ISDIGIT (UCHAR (*++b)); ++logb)
|
||||
;
|
||||
else
|
||||
logb = 0;
|
||||
for (loga = 0; ISDIGIT (tmpa); ++loga)
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (IS_THOUSANDS_SEP (tmpa));
|
||||
|
||||
if ((tmp = loga - logb) != 0)
|
||||
return tmp;
|
||||
for (logb = 0; ISDIGIT (tmpb); ++logb)
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (IS_THOUSANDS_SEP (tmpb));
|
||||
|
||||
if (loga - logb != 0)
|
||||
return loga - logb;
|
||||
|
||||
if (!loga)
|
||||
return 0;
|
||||
|
||||
return tmpa - tmpb;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
general_numcompare (const char *sa, const char *sb)
|
||||
@@ -2510,18 +2343,23 @@ main (int argc, char **argv)
|
||||
{
|
||||
struct lconv *lconvp = localeconv ();
|
||||
|
||||
/* If the locale doesn't define a decimal point, or if the decimal
|
||||
point is multibyte, use the US notation. We don't support
|
||||
multibyte decimal points yet. */
|
||||
decimal_point = *lconvp->decimal_point;
|
||||
th_sep = *lconvp->thousands_sep;
|
||||
if (! decimal_point || lconvp->decimal_point[1])
|
||||
decimal_point = FLOATING_POINT;
|
||||
else
|
||||
nls_fraction_found = 0; /* Figure out which decimal point to use */
|
||||
|
||||
/* We don't support multibyte thousands separators yet. */
|
||||
th_sep = *lconvp->thousands_sep;
|
||||
if (! th_sep || lconvp->thousands_sep[1])
|
||||
th_sep = CHAR_MAX + 1;
|
||||
|
||||
nls_grouping = (char *) (lconvp->grouping);
|
||||
}
|
||||
|
||||
/* if locale doesn't define a decimal point, we'll use the
|
||||
US notation. */
|
||||
if (decimal_point == '\0')
|
||||
decimal_point = FLOATING_POINT;
|
||||
else
|
||||
nls_fraction_found = 0; /* Figure out which decimal point to use */
|
||||
|
||||
nls_month_found = 0; /* Figure out which month notation to use */
|
||||
|
||||
monthtab = nls_monthtab;
|
||||
|
||||
82
src/sys2.h
82
src/sys2.h
@@ -3,14 +3,6 @@
|
||||
more time, I'll merge the remaining things in system.h and everything
|
||||
in this file will go back there. */
|
||||
|
||||
#ifndef UID_T_MAX
|
||||
# define UID_T_MAX TYPE_MAXIMUM (uid_t)
|
||||
#endif
|
||||
|
||||
#ifndef GID_T_MAX
|
||||
# define GID_T_MAX TYPE_MAXIMUM (gid_t)
|
||||
#endif
|
||||
|
||||
#ifndef RETSIGTYPE
|
||||
# define RETSIGTYPE void
|
||||
#endif
|
||||
@@ -62,7 +54,7 @@ char *alloca ();
|
||||
character >= 128 which gets sign-extended to a negative value.
|
||||
The macro ISUPPER protects against this as well." */
|
||||
|
||||
#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
|
||||
#if STDC_HEADERS || (!defined (isascii) && !HAVE_ISASCII)
|
||||
# define IN_CTYPE_DOMAIN(c) 1
|
||||
#else
|
||||
# define IN_CTYPE_DOMAIN(c) isascii(c)
|
||||
@@ -90,6 +82,14 @@ char *alloca ();
|
||||
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
|
||||
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
|
||||
|
||||
#if STDC_HEADERS
|
||||
# define TOLOWER(Ch) tolower (Ch)
|
||||
# define TOUPPER(Ch) toupper (Ch)
|
||||
#else
|
||||
# define TOLOWER(Ch) (ISUPPER (Ch) ? tolower (Ch) : (Ch))
|
||||
# define TOUPPER(Ch) (ISLOWER (Ch) ? toupper (Ch) : (Ch))
|
||||
#endif
|
||||
|
||||
/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
|
||||
- Its arg may be any int or unsigned int; it need not be an unsigned char.
|
||||
- It's guaranteed to evaluate its argument exactly once.
|
||||
@@ -282,3 +282,67 @@ char *base_name PARAMS ((char const *));
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
# define CHAR_BIT 8
|
||||
#endif
|
||||
|
||||
/* The extra casts work around common compiler bugs. */
|
||||
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
||||
/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
|
||||
It is necessary at least when t == time_t. */
|
||||
#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
|
||||
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
|
||||
#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
|
||||
|
||||
#ifndef CHAR_MIN
|
||||
# define CHAR_MIN TYPE_MINIMUM (char)
|
||||
#endif
|
||||
|
||||
#ifndef CHAR_MAX
|
||||
# define CHAR_MAX TYPE_MAXIMUM (char)
|
||||
#endif
|
||||
|
||||
#ifndef SCHAR_MIN
|
||||
# define SCHAR_MIN (-1 - SCHAR_MAX)
|
||||
#endif
|
||||
|
||||
#ifndef SCHAR_MAX
|
||||
# define SCHAR_MAX (CHAR_MAX == UCHAR_MAX ? CHAR_MAX / 2 : CHAR_MAX)
|
||||
#endif
|
||||
|
||||
#ifndef UCHAR_MAX
|
||||
# define UCHAR_MAX TYPE_MAXIMUM (unsigned char)
|
||||
#endif
|
||||
|
||||
#ifndef SHRT_MIN
|
||||
# define SHRT_MIN TYPE_MINIMUM (short int)
|
||||
#endif
|
||||
|
||||
#ifndef SHRT_MAX
|
||||
# define SHRT_MAX TYPE_MAXIMUM (short int)
|
||||
#endif
|
||||
|
||||
#ifndef INT_MAX
|
||||
# define INT_MAX TYPE_MAXIMUM (int)
|
||||
#endif
|
||||
|
||||
#ifndef UINT_MAX
|
||||
# define UINT_MAX TYPE_MAXIMUM (unsigned int)
|
||||
#endif
|
||||
|
||||
#ifndef LONG_MAX
|
||||
# define LONG_MAX TYPE_MAXIMUM (long)
|
||||
#endif
|
||||
|
||||
#ifndef ULONG_MAX
|
||||
# define ULONG_MAX TYPE_MAXIMUM (unsigned long)
|
||||
#endif
|
||||
|
||||
#ifndef UID_T_MAX
|
||||
# define UID_T_MAX TYPE_MAXIMUM (uid_t)
|
||||
#endif
|
||||
|
||||
#ifndef GID_T_MAX
|
||||
# define GID_T_MAX TYPE_MAXIMUM (gid_t)
|
||||
#endif
|
||||
|
||||
75
src/system.h
75
src/system.h
@@ -68,6 +68,18 @@
|
||||
# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
|
||||
#endif
|
||||
|
||||
#if !S_ISUID
|
||||
# define S_ISUID 04000
|
||||
#endif
|
||||
#if !S_ISGID
|
||||
# define S_ISGID 02000
|
||||
#endif
|
||||
|
||||
/* S_ISVTX is a common extension to POSIX.1. */
|
||||
#ifndef S_ISVTX
|
||||
# define S_ISVTX 01000
|
||||
#endif
|
||||
|
||||
#if !S_IWUSR
|
||||
# if S_IWRITE
|
||||
# define S_IWUSR S_IWRITE
|
||||
@@ -97,10 +109,26 @@
|
||||
#ifndef S_IXOTH
|
||||
# define S_IXOTH (S_IEXEC >> 6)
|
||||
#endif
|
||||
|
||||
#ifndef S_IRWXU
|
||||
# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
|
||||
#endif
|
||||
#ifndef S_IRWXG
|
||||
# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
|
||||
#endif
|
||||
#ifndef S_IRWXO
|
||||
# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
|
||||
#endif
|
||||
|
||||
/* S_IXUGO is a common extension to POSIX.1. */
|
||||
#ifndef S_IXUGO
|
||||
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
||||
#endif
|
||||
|
||||
/* All the mode bits that can be affected by chmod. */
|
||||
#define CHMOD_MODE_BITS \
|
||||
(S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
|
||||
|
||||
#ifdef ST_MTIM_NSEC
|
||||
# define ST_TIME_CMP_NS(a, b, ns) ((a).ns < (b).ns ? -1 : (a).ns > (b).ns)
|
||||
#else
|
||||
@@ -145,53 +173,6 @@
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
# define CHAR_BIT 8
|
||||
#endif
|
||||
|
||||
/* The extra casts work around common compiler bugs,
|
||||
e.g. Cray C 5.0.3.0 when t == time_t. */
|
||||
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
||||
#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
|
||||
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
|
||||
#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
|
||||
|
||||
#ifndef CHAR_MIN
|
||||
# define CHAR_MIN TYPE_MINIMUM (char)
|
||||
#endif
|
||||
|
||||
#ifndef CHAR_MAX
|
||||
# define CHAR_MAX TYPE_MAXIMUM (char)
|
||||
#endif
|
||||
|
||||
#ifndef UCHAR_MAX
|
||||
# define UCHAR_MAX TYPE_MAXIMUM (unsigned char)
|
||||
#endif
|
||||
|
||||
#ifndef SHRT_MIN
|
||||
# define SHRT_MIN TYPE_MINIMUM (short int)
|
||||
#endif
|
||||
|
||||
#ifndef SHRT_MAX
|
||||
# define SHRT_MAX TYPE_MAXIMUM (short int)
|
||||
#endif
|
||||
|
||||
#ifndef INT_MAX
|
||||
# define INT_MAX TYPE_MAXIMUM (int)
|
||||
#endif
|
||||
|
||||
#ifndef UINT_MAX
|
||||
# define UINT_MAX TYPE_MAXIMUM (unsigned int)
|
||||
#endif
|
||||
|
||||
#ifndef LONG_MAX
|
||||
# define LONG_MAX TYPE_MAXIMUM (long)
|
||||
#endif
|
||||
|
||||
#ifndef ULONG_MAX
|
||||
# define ULONG_MAX TYPE_MAXIMUM (unsigned long)
|
||||
#endif
|
||||
|
||||
#include "pathmax.h"
|
||||
|
||||
#if TIME_WITH_SYS_TIME
|
||||
|
||||
45
src/touch.c
45
src/touch.c
@@ -83,7 +83,7 @@ static struct option const longopts[] =
|
||||
{"time", required_argument, 0, CHAR_MAX + 1},
|
||||
{"no-create", no_argument, 0, 'c'},
|
||||
{"date", required_argument, 0, 'd'},
|
||||
{"file", required_argument, 0, 'r'},
|
||||
{"file", required_argument, 0, 'r'}, /* FIXME: phase out --file */
|
||||
{"reference", required_argument, 0, 'r'},
|
||||
{GETOPT_HELP_OPTION_DECL},
|
||||
{GETOPT_VERSION_OPTION_DECL},
|
||||
@@ -115,7 +115,8 @@ open_maybe_create (const char *file, int *file_created)
|
||||
while (1)
|
||||
{
|
||||
/* First, see if we can create a new FILE. */
|
||||
fd = open (file, O_WRONLY | O_CREAT | O_EXCL, 0666);
|
||||
fd = open (file, O_WRONLY | O_CREAT | O_EXCL,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
if (fd != -1)
|
||||
*file_created = 1;
|
||||
|
||||
@@ -167,30 +168,44 @@ touch (const char *file)
|
||||
fd = open_maybe_create (file, &file_created);
|
||||
}
|
||||
|
||||
if (fd == -1)
|
||||
/* Don't fail if the open failed because FILE is a directory. */
|
||||
if (fd == -1
|
||||
/* As usual, using E* macros like this is risky...
|
||||
So heads up. */
|
||||
&& errno != EISDIR)
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (file_created && amtime_now)
|
||||
if (amtime_now)
|
||||
{
|
||||
if (close (fd) < 0)
|
||||
if (file_created)
|
||||
{
|
||||
if (close (fd) < 0)
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We've just created the file with the current times. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We're setting only one of the time values. stat the target to get
|
||||
the other one. If we have the file descriptor already, use fstat,
|
||||
otherwise, FILE is a directory, so we have to use stat. */
|
||||
if (fd == -1 ? stat (file, &sbuf) : fstat (fd, &sbuf))
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
close (fd);
|
||||
return 1;
|
||||
}
|
||||
return 0; /* We've done all we have to. */
|
||||
}
|
||||
|
||||
if (fstat (fd, &sbuf))
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (close (fd) < 0)
|
||||
if (fd != -1 && close (fd) < 0)
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
return 1;
|
||||
@@ -251,7 +266,7 @@ usage (int status)
|
||||
Update the access and modification times of each FILE to the current time.\n\
|
||||
\n\
|
||||
-a change only the access time\n\
|
||||
-c do not create any files\n\
|
||||
-c, --no-create do not create any files\n\
|
||||
-d, --date=STRING parse STRING and use it instead of current time\n\
|
||||
-f (ignored)\n\
|
||||
-m change only the modification time\n\
|
||||
|
||||
@@ -181,7 +181,7 @@ search_item (struct item *root, const char *str)
|
||||
else
|
||||
{
|
||||
r = p = s->right;
|
||||
a = +1;
|
||||
a = 1;
|
||||
}
|
||||
|
||||
while (p != q)
|
||||
@@ -194,7 +194,7 @@ search_item (struct item *root, const char *str)
|
||||
}
|
||||
else
|
||||
{
|
||||
p->balance = +1;
|
||||
p->balance = 1;
|
||||
p = p->right;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
#!/bin/sh
|
||||
# Force mv to use the copying code.
|
||||
# Consider the case where SRC and DEST are on a different
|
||||
# Consider the case where SRC and DEST are on different
|
||||
# partitions and DEST is a symlink to SRC.
|
||||
|
||||
: ${MV=mv}
|
||||
: ${RM=rm}
|
||||
: ${LN=ln}
|
||||
|
||||
if test "$VERBOSE" = yes; then
|
||||
set -x
|
||||
$MV --version
|
||||
mv --version
|
||||
fi
|
||||
|
||||
. $srcdir/setup
|
||||
@@ -22,9 +18,9 @@ file="$other_partition_tmpdir/file"
|
||||
symlink=symlink
|
||||
|
||||
framework_failure=0
|
||||
$RM -f $file $symlink || framework_failure=1
|
||||
rm -f $file $symlink || framework_failure=1
|
||||
echo whatever > $file || framework_failure=1
|
||||
$LN -s $file $symlink || framework_failure=1
|
||||
ln -s $file $symlink || framework_failure=1
|
||||
|
||||
if test $framework_failure = 1; then
|
||||
echo 'failure in testing framework'
|
||||
@@ -40,20 +36,21 @@ LANG=C
|
||||
export LANG
|
||||
|
||||
# This mv command should exit nonzero.
|
||||
$MV $file $symlink > out 2>&1 && fail=1
|
||||
mv $symlink $file > out 2>&1 && fail=1
|
||||
|
||||
sed \
|
||||
-e "s,$MV:,XXX:," \
|
||||
-e "s,mv:,XXX:," \
|
||||
-e "s,$file,YYY," \
|
||||
-e "s,$symlink,ZZZ," \
|
||||
out > out2
|
||||
|
||||
cat > exp <<\EOF
|
||||
XXX: `YYY' and `ZZZ' are the same file
|
||||
XXX: `ZZZ' and `YYY' are the same file
|
||||
EOF
|
||||
#'
|
||||
|
||||
cmp out2 exp || fail=1
|
||||
|
||||
$RM -fr out out2 exp $file $symlink $other_partition_tmpdir
|
||||
rm -fr out out2 exp $file $symlink $other_partition_tmpdir
|
||||
|
||||
exit $fail
|
||||
|
||||
@@ -19,7 +19,7 @@ n10b.X n11a.I n11a.X n11b.I n11b.X 01a.I 01a.X 02a.I 02a.X 02b.I 02b.X 02c.I \
|
||||
15c.X 15d.I 15d.X 15e.I 15e.X 16a.I 16a.X 17.I 17.X 18a.I 18a.X 18b.I 18b.X \
|
||||
18c.I 18c.X 18d.I 18d.X 18e.I 18e.X 19a.I 19a.X 19b.I 19b.X 20a.I 20a.X 21a.I \
|
||||
21a.X 21b.I 21b.X 21c.I 21c.X 21d.I 21d.X 21e.I 21e.X 21f.I 21f.X 21g.I 21g.X \
|
||||
22a.I 22a.X 22b.I 22b.X no-file1.X o-no-file1.X
|
||||
22a.I 22a.X 22b.I 22b.X no-file1.X o-no-file1.X neg-nls.I neg-nls.X
|
||||
run_gen = n1.O n1.E n2.O n2.E n3.O n3.E n4.O n4.E n5.O n5.E n6.O n6.E n7.O \
|
||||
n7.E n8a.O n8a.E n8b.O n8b.E n9a.O n9a.E n9b.O n9b.E n10a.O n10a.E n10b.O \
|
||||
n10b.E n11a.O n11a.E n11b.O n11b.E 01a.O 01a.E 02a.O 02a.E 02b.O 02b.E 02c.O \
|
||||
@@ -36,7 +36,8 @@ n10b.E n11a.O n11a.E n11b.O n11b.E 01a.O 01a.E 02a.O 02a.E 02b.O 02b.E 02c.O \
|
||||
15c.E 15d.O 15d.E 15e.O 15e.E 16a.O 16a.E 17.O 17.E 18a.O 18a.E 18b.O 18b.E \
|
||||
18c.O 18c.E 18d.O 18d.E 18e.O 18e.E 19a.O 19a.E 19b.O 19b.E 20a.O 20a.E 21a.O \
|
||||
21a.E 21b.O 21b.E 21c.O 21c.E 21d.O 21d.E 21e.O 21e.E 21f.O 21f.E 21g.O 21g.E \
|
||||
22a.O 22a.E 22b.O 22b.E no-file1.O no-file1.E o-no-file1.O o-no-file1.E
|
||||
22a.O 22a.E 22b.O 22b.E no-file1.O no-file1.E o-no-file1.O o-no-file1.E \
|
||||
neg-nls.O neg-nls.E
|
||||
##test-files-end
|
||||
|
||||
EXTRA_DIST = Test.pm $x-tests $(explicit) $(maint_gen)
|
||||
|
||||
@@ -113,7 +113,7 @@ n10b.X n11a.I n11a.X n11b.I n11b.X 01a.I 01a.X 02a.I 02a.X 02b.I 02b.X 02c.I \
|
||||
15c.X 15d.I 15d.X 15e.I 15e.X 16a.I 16a.X 17.I 17.X 18a.I 18a.X 18b.I 18b.X \
|
||||
18c.I 18c.X 18d.I 18d.X 18e.I 18e.X 19a.I 19a.X 19b.I 19b.X 20a.I 20a.X 21a.I \
|
||||
21a.X 21b.I 21b.X 21c.I 21c.X 21d.I 21d.X 21e.I 21e.X 21f.I 21f.X 21g.I 21g.X \
|
||||
22a.I 22a.X 22b.I 22b.X no-file1.X o-no-file1.X
|
||||
22a.I 22a.X 22b.I 22b.X no-file1.X o-no-file1.X neg-nls.I neg-nls.X
|
||||
|
||||
run_gen = n1.O n1.E n2.O n2.E n3.O n3.E n4.O n4.E n5.O n5.E n6.O n6.E n7.O \
|
||||
n7.E n8a.O n8a.E n8b.O n8b.E n9a.O n9a.E n9b.O n9b.E n10a.O n10a.E n10b.O \
|
||||
@@ -131,7 +131,8 @@ n10b.E n11a.O n11a.E n11b.O n11b.E 01a.O 01a.E 02a.O 02a.E 02b.O 02b.E 02c.O \
|
||||
15c.E 15d.O 15d.E 15e.O 15e.E 16a.O 16a.E 17.O 17.E 18a.O 18a.E 18b.O 18b.E \
|
||||
18c.O 18c.E 18d.O 18d.E 18e.O 18e.E 19a.O 19a.E 19b.O 19b.E 20a.O 20a.E 21a.O \
|
||||
21a.E 21b.O 21b.E 21c.O 21c.E 21d.O 21d.E 21e.O 21e.E 21f.O 21f.E 21g.O 21g.E \
|
||||
22a.O 22a.E 22b.O 22b.E no-file1.O no-file1.E o-no-file1.O o-no-file1.E
|
||||
22a.O 22a.E 22b.O 22b.E no-file1.O no-file1.E o-no-file1.O o-no-file1.E \
|
||||
neg-nls.O neg-nls.E
|
||||
|
||||
|
||||
EXTRA_DIST = Test.pm $x-tests $(explicit) $(maint_gen)
|
||||
|
||||
@@ -203,6 +203,9 @@ my @tv = (
|
||||
# From Will Edgington.
|
||||
["o-no-file1", '-o no-such-file no-such-file', {}, '', 2],
|
||||
|
||||
# From Paul Eggert. This was fixed in textutils-1.22k.
|
||||
["neg-nls", '-n', "-1\n-9\n", "-9\n-1\n", 0],
|
||||
|
||||
);
|
||||
|
||||
sub test_vector
|
||||
|
||||
@@ -1820,8 +1820,25 @@ else
|
||||
esac
|
||||
fi
|
||||
test -s o-no-file1.E || rm -f o-no-file1.E
|
||||
$xx -n $srcdir/neg-nls.I > neg-nls.O 2> neg-nls.E
|
||||
code=$?
|
||||
if test $code != 0 ; then
|
||||
$echo "Test neg-nls failed: ../../src/sort return code $code differs from expected value 0" 1>&2
|
||||
errors=`expr $errors + 1`
|
||||
else
|
||||
cmp neg-nls.O $srcdir/neg-nls.X > /dev/null 2>&1
|
||||
case $? in
|
||||
0) if test "$VERBOSE" ; then $echo "passed neg-nls"; fi ;;
|
||||
1) $echo "Test neg-nls failed: files neg-nls.O and $srcdir/neg-nls.X differ" 1>&2;
|
||||
errors=`expr $errors + 1` ;;
|
||||
2) $echo "Test neg-nls may have failed." 1>&2;
|
||||
$echo The command "cmp neg-nls.O $srcdir/neg-nls.X" failed. 1>&2 ;
|
||||
errors=`expr $errors + 1` ;;
|
||||
esac
|
||||
fi
|
||||
test -s neg-nls.E || rm -f neg-nls.E
|
||||
if test $errors = 0 ; then
|
||||
$echo Passed all 106 tests. 1>&2
|
||||
$echo Passed all 107 tests. 1>&2
|
||||
else
|
||||
$echo Failed $errors tests. 1>&2
|
||||
fi
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
## Process this file with automake to produce Makefile.in -*-Makefile-*-.
|
||||
AUTOMAKE_OPTIONS = 1.3 gnits
|
||||
|
||||
TESTS = empty-file
|
||||
TESTS = empty-file dir-1
|
||||
EXTRA_DIST = $(TESTS)
|
||||
TESTS_ENVIRONMENT = \
|
||||
DF=../../src/df \
|
||||
LN=../../src/ln \
|
||||
LS=../../src/ls \
|
||||
MKDIR=../../src/mkdir \
|
||||
MKNOD=../../src/mknod \
|
||||
MV=../../src/mv \
|
||||
RM=../../src/rm \
|
||||
TOUCH=../../src/touch
|
||||
PATH=../../src:$$PATH
|
||||
|
||||
@@ -99,17 +99,10 @@ l = @l@
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.3 gnits
|
||||
|
||||
TESTS = empty-file
|
||||
TESTS = empty-file dir-1
|
||||
EXTRA_DIST = $(TESTS)
|
||||
TESTS_ENVIRONMENT = \
|
||||
DF=../../src/df \
|
||||
LN=../../src/ln \
|
||||
LS=../../src/ls \
|
||||
MKDIR=../../src/mkdir \
|
||||
MKNOD=../../src/mknod \
|
||||
MV=../../src/mv \
|
||||
RM=../../src/rm \
|
||||
TOUCH=../../src/touch
|
||||
PATH=../../src:$$PATH
|
||||
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../../config.h
|
||||
|
||||
12
tests/touch/dir-1
Executable file
12
tests/touch/dir-1
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
# Make sure touch can operate on a directory.
|
||||
# This was broken in the 4.0[efg] test releases.
|
||||
|
||||
if test "$VERBOSE" = yes; then
|
||||
set -x
|
||||
touch --version
|
||||
fi
|
||||
|
||||
fail=0
|
||||
touch . || fail=1
|
||||
exit $fail
|
||||
@@ -4,12 +4,9 @@
|
||||
# fails to work on SunOS 4.1.3 with `most of the recommended patches' when
|
||||
# the empty file is on an NFS-mounted 4.2 volume.
|
||||
|
||||
: ${RM=rm}
|
||||
: ${TOUCH=touch}
|
||||
|
||||
if test "$VERBOSE" = yes; then
|
||||
set -x
|
||||
$TOUCH --version
|
||||
touch --version
|
||||
fi
|
||||
|
||||
DEFAULT_SLEEP_SECONDS=2
|
||||
@@ -25,7 +22,7 @@ fail=0
|
||||
framework_failure=0
|
||||
|
||||
for d in $TOUCH_DIR_LIST; do
|
||||
$RM -rf $d/a $d/b
|
||||
rm -rf $d/a $d/b
|
||||
> $d/a || framework_failure=1
|
||||
test -f $d/a || framework_failure=1
|
||||
> $d/b || framework_failure=1
|
||||
@@ -39,18 +36,18 @@ fi
|
||||
|
||||
sleep $SLEEP_SECONDS
|
||||
for d in $TOUCH_DIR_LIST; do
|
||||
$TOUCH $d/a || fail=1
|
||||
set x `$LS -t $d/a $d/b`
|
||||
touch $d/a || fail=1
|
||||
set x `ls -t $d/a $d/b`
|
||||
test "$*" = "x $d/a $d/b" || fail=1
|
||||
done
|
||||
|
||||
sleep $SLEEP_SECONDS
|
||||
for d in $TOUCH_DIR_LIST; do
|
||||
$TOUCH $d/b
|
||||
set x `$LS -t $d/a $d/b`
|
||||
touch $d/b
|
||||
set x `ls -t $d/a $d/b`
|
||||
test "$*" = "x $d/b $d/a" || fail=1
|
||||
|
||||
$RM -rf $d/a $d/b
|
||||
rm -rf $d/a $d/b
|
||||
done
|
||||
|
||||
if test $fail != 0; then
|
||||
|
||||
Reference in New Issue
Block a user