findutils: use the HaikuPorts package.
* removed in-tree version. * added as bootstrap package. * note: HaikuPorts package has no rdef for binaries.
This commit is contained in:
@@ -15,7 +15,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
if ! $(HAIKU_BOOTSTRAP_BUILD) {
|
if ! $(HAIKU_BOOTSTRAP_BUILD) {
|
||||||
# primary architecture
|
# primary architecture
|
||||||
AddHaikuImagePackages
|
AddHaikuImagePackages
|
||||||
bzip2 ctags grep sed tar which zlib
|
bzip2 ctags findutils grep sed tar which zlib
|
||||||
ffmpeg freetype icu jpeg libpng libsolv
|
ffmpeg freetype icu jpeg libpng libsolv
|
||||||
mesa mesa_devel mesa_swrast glu
|
mesa mesa_devel mesa_swrast glu
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ rule DefineDefaultBuildProfiles
|
|||||||
bison
|
bison
|
||||||
curl
|
curl
|
||||||
curl_devel
|
curl_devel
|
||||||
|
findutils
|
||||||
flex
|
flex
|
||||||
freetype
|
freetype
|
||||||
freetype_devel
|
freetype_devel
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
|
|||||||
csplit cut date dc dd desklink df diff diff3 dircolors dirname
|
csplit cut date dc dd desklink df diff diff3 dircolors dirname
|
||||||
diskimage draggers driveinfo dstcheck du dumpcatalog
|
diskimage draggers driveinfo dstcheck du dumpcatalog
|
||||||
echo eject env error expand expr
|
echo eject env error expand expr
|
||||||
factor false fdinfo ffm filepanel find finddir findpaths FirstBootPrompt fmt
|
factor false fdinfo ffm filepanel finddir findpaths FirstBootPrompt fmt
|
||||||
fold fortune frcode fstrim ftp ftpd funzip fwcontrol@x86
|
fold fortune fstrim ftp ftpd funzip fwcontrol@x86
|
||||||
gawk gdb@x86 getarch getlimits groupadd groupdel groupmod groups gzip gzexe
|
gawk gdb@x86 getarch getlimits groupadd groupdel groupmod groups gzip gzexe
|
||||||
hd head hey hostname
|
hd head hey hostname
|
||||||
id ident ifconfig <bin>install installsound iroster isvolume
|
id ident ifconfig <bin>install installsound iroster isvolume
|
||||||
ideinfo@ide idestatus@ide
|
ideinfo@ide idestatus@ide
|
||||||
join kernel_debugger keymap keystore kill
|
join kernel_debugger keymap keystore kill
|
||||||
less lessecho lesskey link linkcatkeys listarea listattr listimage listdev
|
less lessecho lesskey link linkcatkeys listarea listattr listimage listdev
|
||||||
listport listres listsem listusb ln locale locate logger login logname ls
|
listport listres listsem listusb ln locale logger login logname ls
|
||||||
lsindex
|
lsindex
|
||||||
mail2mbox makebootable mbox2mail md5sum merge message mimeset mkdos mkdir
|
mail2mbox makebootable mbox2mail md5sum merge message mimeset mkdos mkdir
|
||||||
mkfifo mkfs mkindex mktemp modifiers mount mount_nfs mountvolume mv
|
mkfifo mkfs mkindex mktemp modifiers mount mount_nfs mountvolume mv
|
||||||
@@ -37,9 +37,9 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
|
|||||||
tac tail tcpdump tcptester tee telnet telnetd test timeout top touch
|
tac tail tcpdump tcptester tee telnet telnetd test timeout top touch
|
||||||
tr traceroute translate trash true truncate tsort tty
|
tr traceroute translate trash true truncate tsort tty
|
||||||
uname unchop unexpand unmount uniq unlink unshar unzip unzipsfx
|
uname unchop unexpand unmount uniq unlink unshar unzip unzipsfx
|
||||||
<bin>updatedb uptime urlwrapper useradd userdel uudecode uuencode
|
uptime urlwrapper useradd userdel uudecode uuencode
|
||||||
vdir version vmstat
|
vdir version vmstat
|
||||||
waitfor watch wc wget whoami writembr@x86,x86_64 xargs xres
|
waitfor watch wc wget whoami writembr@x86,x86_64 xres
|
||||||
yes
|
yes
|
||||||
zdiff zforce zgrep zip zipcloak <bin>zipgrep zipnote zipsplit zmore znew
|
zdiff zforce zgrep zip zipcloak <bin>zipgrep zipnote zipsplit zmore znew
|
||||||
] ;
|
] ;
|
||||||
|
|||||||
@@ -261,7 +261,6 @@ SubInclude HAIKU_TOP src bin consoled ;
|
|||||||
SubInclude HAIKU_TOP src bin coreutils ;
|
SubInclude HAIKU_TOP src bin coreutils ;
|
||||||
SubInclude HAIKU_TOP src bin desklink ;
|
SubInclude HAIKU_TOP src bin desklink ;
|
||||||
SubInclude HAIKU_TOP src bin diffutils ;
|
SubInclude HAIKU_TOP src bin diffutils ;
|
||||||
SubInclude HAIKU_TOP src bin findutils ;
|
|
||||||
SubInclude HAIKU_TOP src bin fwcontrol ;
|
SubInclude HAIKU_TOP src bin fwcontrol ;
|
||||||
SubInclude HAIKU_TOP src bin gawk ;
|
SubInclude HAIKU_TOP src bin gawk ;
|
||||||
SubInclude HAIKU_TOP src bin gdb ;
|
SubInclude HAIKU_TOP src bin gdb ;
|
||||||
|
|||||||
@@ -1,676 +0,0 @@
|
|||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains free
|
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
|
||||||
any other work released this way by its authors. You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
||||||
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
SubDir HAIKU_TOP src bin findutils ;
|
|
||||||
|
|
||||||
SubInclude HAIKU_TOP src bin findutils gnulib ;
|
|
||||||
SubInclude HAIKU_TOP src bin findutils lib ;
|
|
||||||
SubInclude HAIKU_TOP src bin findutils find ;
|
|
||||||
SubInclude HAIKU_TOP src bin findutils locate ;
|
|
||||||
SubInclude HAIKU_TOP src bin findutils xargs ;
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
This package contains the GNU find, xargs, and locate programs. find
|
|
||||||
and xargs comply with POSIX 1003.2, as far as I know (with the
|
|
||||||
exception of the "+" modifier for the "-exec" action, which isn't
|
|
||||||
implemented yet). They also support a large number of additional
|
|
||||||
options, some borrowed from Unix and some unique to GNU.
|
|
||||||
|
|
||||||
See the file NEWS for a list of major changes in the current release.
|
|
||||||
|
|
||||||
See the file INSTALL for compilation and installation instructions.
|
|
||||||
|
|
||||||
To verify the GPG signature of the release, you will need the public
|
|
||||||
key of the findutils maintainer. You can download this from
|
|
||||||
ftp://ftp.gnu.org/gnu/gnu-keyring.gpg. Alternatively, you could query
|
|
||||||
a PGP keyserver, but you will need to use one that can cope with
|
|
||||||
subkeys containing photos. Many older key servers cannot do this. I
|
|
||||||
use subkeys.pgp.net. I think that one works. See also the
|
|
||||||
"Downloading" section of http://www.gnu.org/software/findutils/.
|
|
||||||
|
|
||||||
Special configure options:
|
|
||||||
|
|
||||||
--with-afs
|
|
||||||
Make find support "-fstype afs". Requires /afs, /usr/afsws/lib, and
|
|
||||||
/usr/afsws/include. configure doesn't add AFS support
|
|
||||||
automatically because it adds considerably to find's size, and the
|
|
||||||
AFS libraries need -lucb on Solaris, which breaks find.
|
|
||||||
|
|
||||||
--enable-id-cache
|
|
||||||
Make tables of used UIDs and GIDs at startup instead of using
|
|
||||||
getpwuid or getgrgid when needed. Speeds up -nouser and -nogroup
|
|
||||||
unless you are running NIS or Hesiod, which make password and group
|
|
||||||
calls very expensive.
|
|
||||||
|
|
||||||
--enable-debug
|
|
||||||
Produce output on the standard error output indicating what find is
|
|
||||||
doing. This information includes details about how the command line
|
|
||||||
has been parsed and what files have been stat()ed. This output is
|
|
||||||
normally interesting only to the maintainer, and so is off by default.
|
|
||||||
|
|
||||||
|
|
||||||
To gain speed, GNU find avoids statting files whenever possible.
|
|
||||||
It does this by:
|
|
||||||
1. Checking the number of links to directories and not statting files
|
|
||||||
that it knows aren't directories until it encounters a test or action
|
|
||||||
that needs the stat info.
|
|
||||||
2. Rearranging the command line, where possible, so that it can do tests
|
|
||||||
that don't require a stat before tests that do, in hopes that the
|
|
||||||
latter will be skipped because of an OR or AND. (But it only does
|
|
||||||
this where it will leave the output unchanged.)
|
|
||||||
|
|
||||||
The locate program and its helper programs are derived (heavily
|
|
||||||
modified) from James Woods' public domain fast-find code, which is
|
|
||||||
also distributed with the 4.3BSD find. Because POSIX.2 requires `find
|
|
||||||
foo' to have the same effect as `find foo -print', the fast-find
|
|
||||||
searching has been moved to a separate program, `locate'; the same
|
|
||||||
thing has been done in 4.4BSD. If you use locate, you should run the
|
|
||||||
included `updatedb' script from cron periodically (typically nightly).
|
|
||||||
|
|
||||||
Mail suggestions and bug reports for these programs to
|
|
||||||
[email protected].
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
|||||||
SubDir HAIKU_TOP src bin findutils find ;
|
|
||||||
|
|
||||||
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) gnulib lib ] ;
|
|
||||||
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) lib ] ;
|
|
||||||
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ;
|
|
||||||
|
|
||||||
# filter warnings we don't want here
|
|
||||||
TARGET_WARNING_CCFLAGS_$(TARGET_PACKAGING_ARCH)
|
|
||||||
= [ FFilter $(TARGET_WARNING_CCFLAGS_$(TARGET_PACKAGING_ARCH))
|
|
||||||
: -Wall -Wmissing-prototypes -Wsign-compare ] ;
|
|
||||||
|
|
||||||
# set some additional defines
|
|
||||||
{
|
|
||||||
SubDirCcFlags -DHAVE_CONFIG_H ;
|
|
||||||
}
|
|
||||||
|
|
||||||
BinCommand find :
|
|
||||||
find.c
|
|
||||||
fstype.c
|
|
||||||
parser.c
|
|
||||||
pred.c
|
|
||||||
tree.c
|
|
||||||
util.c
|
|
||||||
: libfindutils.a gnulibfindutils.a : findutils.rdef ;
|
|
||||||
|
|
||||||
SEARCH on [ FGristFiles findutils.rdef ] = [ FDirName $(SUBDIR) $(DOTDOT) ] ;
|
|
||||||
@@ -1,611 +0,0 @@
|
|||||||
/* defs.h -- data types and declarations.
|
|
||||||
Copyright (C) 1990, 91, 92, 93, 94, 2000, 2001, 2003, 2004, 2005, 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef INC_DEFS_H
|
|
||||||
#define INC_DEFS_H 1
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#include <strings.h>
|
|
||||||
#ifndef strchr
|
|
||||||
#define strchr index
|
|
||||||
#endif
|
|
||||||
#ifndef strrchr
|
|
||||||
#define strrchr rindex
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#ifndef errno
|
|
||||||
extern int errno;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STDC_HEADERS
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The presence of unistd.h is assumed by gnulib these days, so we
|
|
||||||
* might as well assume it too.
|
|
||||||
*/
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#if HAVE_LIMITS_H
|
|
||||||
# include <limits.h>
|
|
||||||
#endif
|
|
||||||
#ifndef CHAR_BIT
|
|
||||||
# define CHAR_BIT 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_INTTYPES_H
|
|
||||||
# include <inttypes.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "regex.h"
|
|
||||||
|
|
||||||
#ifndef S_IFLNK
|
|
||||||
#define lstat stat
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# ifndef PARAMS
|
|
||||||
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
|
|
||||||
# define PARAMS(Args) Args
|
|
||||||
# else
|
|
||||||
# define PARAMS(Args) ()
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
int lstat PARAMS((const char *__path, struct stat *__statbuf));
|
|
||||||
int stat PARAMS((const char *__path, struct stat *__statbuf));
|
|
||||||
|
|
||||||
int optionl_stat PARAMS((const char *name, struct stat *p));
|
|
||||||
int optionp_stat PARAMS((const char *name, struct stat *p));
|
|
||||||
int optionh_stat PARAMS((const char *name, struct stat *p));
|
|
||||||
|
|
||||||
int get_statinfo PARAMS((const char *pathname, const char *name, struct stat *p));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef S_ISUID
|
|
||||||
# define S_ISUID 0004000
|
|
||||||
#endif
|
|
||||||
#ifndef S_ISGID
|
|
||||||
# define S_ISGID 0002000
|
|
||||||
#endif
|
|
||||||
#ifndef S_ISVTX
|
|
||||||
# define S_ISVTX 0001000
|
|
||||||
#endif
|
|
||||||
#ifndef S_IRUSR
|
|
||||||
# define S_IRUSR 0000400
|
|
||||||
#endif
|
|
||||||
#ifndef S_IWUSR
|
|
||||||
# define S_IWUSR 0000200
|
|
||||||
#endif
|
|
||||||
#ifndef S_IXUSR
|
|
||||||
# define S_IXUSR 0000100
|
|
||||||
#endif
|
|
||||||
#ifndef S_IRGRP
|
|
||||||
# define S_IRGRP 0000040
|
|
||||||
#endif
|
|
||||||
#ifndef S_IWGRP
|
|
||||||
# define S_IWGRP 0000020
|
|
||||||
#endif
|
|
||||||
#ifndef S_IXGRP
|
|
||||||
# define S_IXGRP 0000010
|
|
||||||
#endif
|
|
||||||
#ifndef S_IROTH
|
|
||||||
# define S_IROTH 0000004
|
|
||||||
#endif
|
|
||||||
#ifndef S_IWOTH
|
|
||||||
# define S_IWOTH 0000002
|
|
||||||
#endif
|
|
||||||
#ifndef S_IXOTH
|
|
||||||
# define S_IXOTH 0000001
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MODE_WXUSR (S_IWUSR | S_IXUSR)
|
|
||||||
#define MODE_R (S_IRUSR | S_IRGRP | S_IROTH)
|
|
||||||
#define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
|
|
||||||
#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
|
|
||||||
#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
#include <stdbool.h>
|
|
||||||
typedef bool boolean;
|
|
||||||
#else
|
|
||||||
/* Not char because of type promotion; NeXT gcc can't handle it. */
|
|
||||||
typedef int boolean;
|
|
||||||
#define true 1
|
|
||||||
#define false 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct predicate;
|
|
||||||
|
|
||||||
/* Pointer to a predicate function. */
|
|
||||||
typedef boolean (*PRED_FUNC)(char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
|
|
||||||
|
|
||||||
/* The number of seconds in a day. */
|
|
||||||
#define DAYSECS 86400
|
|
||||||
|
|
||||||
/* Argument structures for predicates. */
|
|
||||||
|
|
||||||
enum comparison_type
|
|
||||||
{
|
|
||||||
COMP_GT,
|
|
||||||
COMP_LT,
|
|
||||||
COMP_EQ
|
|
||||||
};
|
|
||||||
|
|
||||||
enum permissions_type
|
|
||||||
{
|
|
||||||
PERM_AT_LEAST,
|
|
||||||
PERM_ANY,
|
|
||||||
PERM_EXACT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum predicate_type
|
|
||||||
{
|
|
||||||
NO_TYPE,
|
|
||||||
PRIMARY_TYPE,
|
|
||||||
UNI_OP,
|
|
||||||
BI_OP,
|
|
||||||
OPEN_PAREN,
|
|
||||||
CLOSE_PAREN
|
|
||||||
};
|
|
||||||
|
|
||||||
enum predicate_precedence
|
|
||||||
{
|
|
||||||
NO_PREC,
|
|
||||||
COMMA_PREC,
|
|
||||||
OR_PREC,
|
|
||||||
AND_PREC,
|
|
||||||
NEGATE_PREC,
|
|
||||||
MAX_PREC
|
|
||||||
};
|
|
||||||
|
|
||||||
struct long_val
|
|
||||||
{
|
|
||||||
enum comparison_type kind;
|
|
||||||
boolean negative; /* Defined only when representing time_t. */
|
|
||||||
uintmax_t l_val;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct perm_val
|
|
||||||
{
|
|
||||||
enum permissions_type kind;
|
|
||||||
mode_t val[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* dir_id is used to support loop detection in find.c and
|
|
||||||
* also to support the -samefile test.
|
|
||||||
*/
|
|
||||||
struct dir_id
|
|
||||||
{
|
|
||||||
ino_t ino;
|
|
||||||
dev_t dev;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct size_val
|
|
||||||
{
|
|
||||||
enum comparison_type kind;
|
|
||||||
int blocksize;
|
|
||||||
uintmax_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NEW_EXEC 1
|
|
||||||
/*
|
|
||||||
#undef NEW_EXEC
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NEW_EXEC)
|
|
||||||
struct path_arg
|
|
||||||
{
|
|
||||||
short offset; /* Offset in `vec' of this arg. */
|
|
||||||
short count; /* Number of path replacements in this arg. */
|
|
||||||
char *origarg; /* Arg with "{}" intact. */
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "buildcmd.h"
|
|
||||||
|
|
||||||
struct exec_val
|
|
||||||
{
|
|
||||||
#if defined(NEW_EXEC)
|
|
||||||
/* new-style */
|
|
||||||
boolean multiple; /* -exec {} \+ denotes multiple argument. */
|
|
||||||
struct buildcmd_control ctl;
|
|
||||||
struct buildcmd_state state;
|
|
||||||
char **replace_vec; /* Command arguments (for ";" style) */
|
|
||||||
int num_args;
|
|
||||||
boolean use_current_dir; /* If nonzero, don't chdir to start dir */
|
|
||||||
boolean close_stdin; /* If true, close stdin in the child. */
|
|
||||||
#else
|
|
||||||
struct path_arg *paths; /* Array of args with path replacements. */
|
|
||||||
char **vec; /* Array of args to pass to program. */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The format string for a -printf or -fprintf is chopped into one or
|
|
||||||
more `struct segment', linked together into a list.
|
|
||||||
Each stretch of plain text is a segment, and
|
|
||||||
each \c and `%' conversion is a segment. */
|
|
||||||
|
|
||||||
/* Special values for the `kind' field of `struct segment'. */
|
|
||||||
#define KIND_PLAIN 0 /* Segment containing just plain text. */
|
|
||||||
#define KIND_STOP 1 /* \c -- stop printing and flush output. */
|
|
||||||
|
|
||||||
struct segment
|
|
||||||
{
|
|
||||||
int kind; /* Format chars or KIND_{PLAIN,STOP}. */
|
|
||||||
char *text; /* Plain text or `%' format string. */
|
|
||||||
int text_len; /* Length of `text'. */
|
|
||||||
struct segment *next; /* Next segment for this predicate. */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct format_val
|
|
||||||
{
|
|
||||||
struct segment *segment; /* Linked list of segments. */
|
|
||||||
FILE *stream; /* Output stream to print on. */
|
|
||||||
boolean dest_is_tty; /* True if the destination is a terminal. */
|
|
||||||
struct quoting_options *quote_opts;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct predicate
|
|
||||||
{
|
|
||||||
/* Pointer to the function that implements this predicate. */
|
|
||||||
PRED_FUNC pred_func;
|
|
||||||
|
|
||||||
/* Only used for debugging, but defined unconditionally so individual
|
|
||||||
modules can be compiled with -DDEBUG. */
|
|
||||||
char *p_name;
|
|
||||||
|
|
||||||
/* The type of this node. There are two kinds. The first is real
|
|
||||||
predicates ("primaries") such as -perm, -print, or -exec. The
|
|
||||||
other kind is operators for combining predicates. */
|
|
||||||
enum predicate_type p_type;
|
|
||||||
|
|
||||||
/* The precedence of this node. Only has meaning for operators. */
|
|
||||||
enum predicate_precedence p_prec;
|
|
||||||
|
|
||||||
/* True if this predicate node produces side effects.
|
|
||||||
If side_effects are produced
|
|
||||||
then optimization will not be performed */
|
|
||||||
boolean side_effects;
|
|
||||||
|
|
||||||
/* True if this predicate node requires default print be turned off. */
|
|
||||||
boolean no_default_print;
|
|
||||||
|
|
||||||
/* True if this predicate node requires a stat system call to execute. */
|
|
||||||
boolean need_stat;
|
|
||||||
|
|
||||||
/* True if this predicate node requires knowledge of the file type. */
|
|
||||||
boolean need_type;
|
|
||||||
|
|
||||||
/* Information needed by the predicate processor.
|
|
||||||
Next to each member are listed the predicates that use it. */
|
|
||||||
union
|
|
||||||
{
|
|
||||||
char *str; /* fstype [i]lname [i]name [i]path */
|
|
||||||
struct re_pattern_buffer *regex; /* regex */
|
|
||||||
struct exec_val exec_vec; /* exec ok */
|
|
||||||
struct long_val info; /* atime ctime gid inum links mtime
|
|
||||||
size uid */
|
|
||||||
struct size_val size; /* size */
|
|
||||||
uid_t uid; /* user */
|
|
||||||
gid_t gid; /* group */
|
|
||||||
time_t time; /* newer */
|
|
||||||
struct perm_val perm; /* perm */
|
|
||||||
struct dir_id fileid; /* samefile */
|
|
||||||
mode_t type; /* type */
|
|
||||||
FILE *stream; /* ls fls fprint0 */
|
|
||||||
struct format_val printf_vec; /* printf fprintf fprint */
|
|
||||||
} args;
|
|
||||||
|
|
||||||
/* The next predicate in the user input sequence,
|
|
||||||
which represents the order in which the user supplied the
|
|
||||||
predicates on the command line. */
|
|
||||||
struct predicate *pred_next;
|
|
||||||
|
|
||||||
/* The right and left branches from this node in the expression
|
|
||||||
tree, which represents the order in which the nodes should be
|
|
||||||
processed. */
|
|
||||||
struct predicate *pred_left;
|
|
||||||
struct predicate *pred_right;
|
|
||||||
|
|
||||||
const struct parser_table* parser_entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* find.c. */
|
|
||||||
int get_info PARAMS((const char *pathname, const char *name, struct stat *p, struct predicate *pred_ptr));
|
|
||||||
int following_links(void);
|
|
||||||
|
|
||||||
|
|
||||||
/* find library function declarations. */
|
|
||||||
|
|
||||||
/* dirname.c */
|
|
||||||
char *dirname PARAMS((char *path));
|
|
||||||
|
|
||||||
/* error.c */
|
|
||||||
void error PARAMS((int status, int errnum, char *message, ...));
|
|
||||||
|
|
||||||
/* listfile.c */
|
|
||||||
void list_file PARAMS((char *name, char *relname, struct stat *statp, time_t current_time, int output_block_size, FILE *stream));
|
|
||||||
char *get_link_name PARAMS((char *name, char *relname));
|
|
||||||
|
|
||||||
/* stpcpy.c */
|
|
||||||
#if !HAVE_STPCPY
|
|
||||||
char *stpcpy PARAMS((char *dest, const char *src));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* xgetcwd.c */
|
|
||||||
char *xgetcwd PARAMS((void));
|
|
||||||
|
|
||||||
/* xmalloc.c */
|
|
||||||
#if __STDC__
|
|
||||||
#define VOID void
|
|
||||||
#else
|
|
||||||
#define VOID char
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* find global function declarations. */
|
|
||||||
|
|
||||||
/* find.c */
|
|
||||||
/* SymlinkOption represents the choice of
|
|
||||||
* -P, -L or -P (default) on the command line.
|
|
||||||
*/
|
|
||||||
enum SymlinkOption
|
|
||||||
{
|
|
||||||
SYMLINK_NEVER_DEREF, /* Option -P */
|
|
||||||
SYMLINK_ALWAYS_DEREF, /* Option -L */
|
|
||||||
SYMLINK_DEREF_ARGSONLY /* Option -H */
|
|
||||||
};
|
|
||||||
extern enum SymlinkOption symlink_handling; /* defined in find.c. */
|
|
||||||
|
|
||||||
void set_follow_state PARAMS((enum SymlinkOption opt));
|
|
||||||
void cleanup(void);
|
|
||||||
|
|
||||||
/* fstype.c */
|
|
||||||
char *filesystem_type PARAMS((const struct stat *statp, const char *path));
|
|
||||||
char * get_mounted_filesystems (void);
|
|
||||||
dev_t * get_mounted_devices PARAMS((size_t *));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum arg_type
|
|
||||||
{
|
|
||||||
ARG_OPTION, /* regular options like -maxdepth */
|
|
||||||
ARG_POSITIONAL_OPTION, /* options whose position is important (-follow) */
|
|
||||||
ARG_TEST, /* a like -name */
|
|
||||||
ARG_PUNCTUATION, /* like -o or ( */
|
|
||||||
ARG_ACTION /* like -print */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct parser_table;
|
|
||||||
/* Pointer to a parser function. */
|
|
||||||
typedef boolean (*PARSE_FUNC)(const struct parser_table *p,
|
|
||||||
char *argv[], int *arg_ptr);
|
|
||||||
struct parser_table
|
|
||||||
{
|
|
||||||
enum arg_type type;
|
|
||||||
char *parser_name;
|
|
||||||
PARSE_FUNC parser_func;
|
|
||||||
PRED_FUNC pred_func;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* parser.c */
|
|
||||||
const struct parser_table* find_parser PARAMS((char *search_name));
|
|
||||||
boolean parse_open PARAMS((const struct parser_table* entry, char *argv[], int *arg_ptr));
|
|
||||||
boolean parse_close PARAMS((const struct parser_table* entry, char *argv[], int *arg_ptr));
|
|
||||||
boolean parse_print PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
|
|
||||||
void pred_sanity_check PARAMS((const struct predicate *predicates));
|
|
||||||
void parse_begin_user_args PARAMS((char **args, int argno, const struct predicate *last, const struct predicate *predicates));
|
|
||||||
void parse_end_user_args PARAMS((char **args, int argno, const struct predicate *last, const struct predicate *predicates));
|
|
||||||
boolean parse_openparen PARAMS((const struct parser_table* entry, char *argv[], int *arg_ptr));
|
|
||||||
boolean parse_closeparen PARAMS((const struct parser_table* entry, char *argv[], int *arg_ptr));
|
|
||||||
|
|
||||||
/* pred.c */
|
|
||||||
boolean pred_amin PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_and PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_anewer PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_atime PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_closeparen PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_cmin PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_cnewer PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_comma PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_ctime PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_delete PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_empty PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_exec PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_execdir PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_false PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_fls PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_fprint PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_fprint0 PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_fprintf PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_fstype PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_gid PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_group PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_ilname PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_iname PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_inum PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_ipath PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_links PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_lname PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_ls PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_mmin PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_mtime PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_name PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_negate PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_newer PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_nogroup PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_nouser PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_ok PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_okdir PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_openparen PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_or PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_path PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_perm PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_print PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_print0 PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_prune PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_quit PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_regex PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_samefile PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_size PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_true PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_type PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_uid PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_used PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_user PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
boolean pred_xtype PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int launch PARAMS((const struct buildcmd_control *ctl,
|
|
||||||
struct buildcmd_state *buildstate));
|
|
||||||
|
|
||||||
|
|
||||||
char *find_pred_name PARAMS((PRED_FUNC pred_func));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
void print_tree PARAMS((FILE*, struct predicate *node, int indent));
|
|
||||||
void print_list PARAMS((FILE*, struct predicate *node));
|
|
||||||
void print_optlist PARAMS((FILE *fp, struct predicate *node));
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/* tree.c */
|
|
||||||
struct predicate *
|
|
||||||
get_expr PARAMS((struct predicate **input, short int prev_prec));
|
|
||||||
boolean opt_expr PARAMS((struct predicate **eval_treep));
|
|
||||||
boolean mark_stat PARAMS((struct predicate *tree));
|
|
||||||
boolean mark_type PARAMS((struct predicate *tree));
|
|
||||||
|
|
||||||
/* util.c */
|
|
||||||
struct predicate *get_new_pred PARAMS((const struct parser_table *entry));
|
|
||||||
struct predicate *get_new_pred_chk_op PARAMS((const struct parser_table *entry));
|
|
||||||
struct predicate *insert_primary PARAMS((const struct parser_table *entry));
|
|
||||||
struct predicate *insert_primary_withpred PARAMS((const struct parser_table *entry, PRED_FUNC fptr));
|
|
||||||
void usage PARAMS((char *msg));
|
|
||||||
|
|
||||||
extern char *program_name;
|
|
||||||
extern struct predicate *predicates;
|
|
||||||
extern struct predicate *last_pred;
|
|
||||||
|
|
||||||
struct options
|
|
||||||
{
|
|
||||||
/* If true, process directory before contents. True unless -depth given. */
|
|
||||||
boolean do_dir_first;
|
|
||||||
|
|
||||||
/* If >=0, don't descend more than this many levels of subdirectories. */
|
|
||||||
int maxdepth;
|
|
||||||
|
|
||||||
/* If >=0, don't process files above this level. */
|
|
||||||
int mindepth;
|
|
||||||
|
|
||||||
/* If true, do not assume that files in directories with nlink == 2
|
|
||||||
are non-directories. */
|
|
||||||
boolean no_leaf_check;
|
|
||||||
|
|
||||||
/* If true, don't cross filesystem boundaries. */
|
|
||||||
boolean stay_on_filesystem;
|
|
||||||
|
|
||||||
/* If true, we ignore the problem where we find that a directory entry
|
|
||||||
* no longer exists by the time we get around to processing it.
|
|
||||||
*/
|
|
||||||
boolean ignore_readdir_race;
|
|
||||||
|
|
||||||
/* If true, we issue warning messages
|
|
||||||
*/
|
|
||||||
boolean warnings;
|
|
||||||
time_t start_time; /* Time at start of execution. */
|
|
||||||
|
|
||||||
/* Seconds between 00:00 1/1/70 and either one day before now
|
|
||||||
(the default), or the start of today (if -daystart is given). */
|
|
||||||
time_t cur_day_start;
|
|
||||||
|
|
||||||
/* If true, cur_day_start has been adjusted to the start of the day. */
|
|
||||||
boolean full_days;
|
|
||||||
|
|
||||||
int output_block_size; /* Output block size. */
|
|
||||||
|
|
||||||
enum SymlinkOption symlink_handling;
|
|
||||||
|
|
||||||
|
|
||||||
/* Pointer to the function used to stat files. */
|
|
||||||
int (*xstat) (const char *name, struct stat *statbuf);
|
|
||||||
|
|
||||||
|
|
||||||
/* Indicate if we can implement safely_chdir() using the O_NOFOLLOW
|
|
||||||
* flag to open(2).
|
|
||||||
*/
|
|
||||||
boolean open_nofollow_available;
|
|
||||||
|
|
||||||
/* The variety of regular expression that we support.
|
|
||||||
* The default is POSIX Basic Regular Expressions, but this
|
|
||||||
* can be changed with the positional option, -regextype.
|
|
||||||
*/
|
|
||||||
int regex_options;
|
|
||||||
};
|
|
||||||
extern struct options options;
|
|
||||||
|
|
||||||
|
|
||||||
struct state
|
|
||||||
{
|
|
||||||
/* Current depth; 0 means current path is a command line arg. */
|
|
||||||
int curdepth;
|
|
||||||
|
|
||||||
/* If true, we have called stat on the current path. */
|
|
||||||
boolean have_stat;
|
|
||||||
|
|
||||||
/* If true, we know the type of the current path. */
|
|
||||||
boolean have_type;
|
|
||||||
mode_t type; /* this is the actual type */
|
|
||||||
|
|
||||||
/* The file being operated on, relative to the current directory.
|
|
||||||
Used for stat, readlink, remove, and opendir. */
|
|
||||||
char *rel_pathname;
|
|
||||||
|
|
||||||
/* Length of current path. */
|
|
||||||
int path_length;
|
|
||||||
|
|
||||||
/* If true, don't descend past current directory.
|
|
||||||
Can be set by -prune, -maxdepth, and -xdev/-mount. */
|
|
||||||
boolean stop_at_current_level;
|
|
||||||
|
|
||||||
/* Status value to return to system. */
|
|
||||||
int exit_status;
|
|
||||||
};
|
|
||||||
extern struct state state;
|
|
||||||
|
|
||||||
extern char const *starting_dir;
|
|
||||||
extern int starting_desc;
|
|
||||||
#if ! defined HAVE_FCHDIR && ! defined fchdir
|
|
||||||
# define fchdir(fd) (-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,312 +0,0 @@
|
|||||||
/* fstype.c -- determine type of filesystems that files are on
|
|
||||||
Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003, 2004, 2005 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Written by David MacKenzie <[email protected]>.
|
|
||||||
*
|
|
||||||
* Converted to use gnulib's read_file_system_list()
|
|
||||||
* by James Youngman <[email protected]> (which saves a lot
|
|
||||||
* of manual hacking of configure.in).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The presence of unistd.h is assumed by gnulib these days, so we
|
|
||||||
* might as well assume it too.
|
|
||||||
*/
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_MNTIO_H
|
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/mntio.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_MKDEV_H
|
|
||||||
#include <sys/mkdev.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STDC_HEADERS
|
|
||||||
#include <stdlib.h>
|
|
||||||
#else
|
|
||||||
extern int errno;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
#include "../gnulib/lib/dirname.h"
|
|
||||||
#include "xalloc.h"
|
|
||||||
#include "modetype.h"
|
|
||||||
|
|
||||||
/* Need declaration of function `xstrtoumax' */
|
|
||||||
#include "../gnulib/lib/xstrtol.h"
|
|
||||||
|
|
||||||
#include "extendbuf.h"
|
|
||||||
#include "mountlist.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_NLS
|
|
||||||
# include <libintl.h>
|
|
||||||
# define _(Text) gettext (Text)
|
|
||||||
#else
|
|
||||||
# define _(Text) Text
|
|
||||||
#endif
|
|
||||||
#ifdef gettext_noop
|
|
||||||
# define N_(String) gettext_noop (String)
|
|
||||||
#else
|
|
||||||
/* See locate.c for explanation as to why not use (String) */
|
|
||||||
# define N_(String) String
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static char *filesystem_type_uncached PARAMS((const struct stat *statp, const char *path));
|
|
||||||
|
|
||||||
|
|
||||||
/* Get MNTTYPE_IGNORE if it is available. */
|
|
||||||
#if HAVE_MNTENT_H
|
|
||||||
# include <mntent.h>
|
|
||||||
#endif
|
|
||||||
#if HAVE_SYS_MNTTAB_H
|
|
||||||
# include <stdio.h>
|
|
||||||
# include <sys/mnttab.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_file_system_list(struct mount_entry *p)
|
|
||||||
{
|
|
||||||
while (p)
|
|
||||||
{
|
|
||||||
struct mount_entry *pnext = p->me_next;
|
|
||||||
|
|
||||||
free(p->me_devname);
|
|
||||||
free(p->me_mountdir);
|
|
||||||
|
|
||||||
if(p->me_type_malloced)
|
|
||||||
free(p->me_type);
|
|
||||||
p->me_next = NULL;
|
|
||||||
free(p);
|
|
||||||
p = pnext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef AFS
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <afs/venus.h>
|
|
||||||
#if __STDC__
|
|
||||||
/* On SunOS 4, afs/vice.h defines this to rely on a pre-ANSI cpp. */
|
|
||||||
#undef _VICEIOCTL
|
|
||||||
#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
|
|
||||||
#endif
|
|
||||||
#ifndef _IOW
|
|
||||||
/* AFS on Solaris 2.3 doesn't get this definition. */
|
|
||||||
#include <sys/ioccom.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
|
||||||
in_afs (char *path)
|
|
||||||
{
|
|
||||||
static char space[2048];
|
|
||||||
struct ViceIoctl vi;
|
|
||||||
|
|
||||||
vi.in_size = 0;
|
|
||||||
vi.out_size = sizeof (space);
|
|
||||||
vi.out = space;
|
|
||||||
|
|
||||||
if (pioctl (path, VIOC_FILE_CELL_NAME, &vi, 1)
|
|
||||||
&& (errno == EINVAL || errno == ENOENT))
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif /* AFS */
|
|
||||||
|
|
||||||
/* Nonzero if the current filesystem's type is known. */
|
|
||||||
static int fstype_known = 0;
|
|
||||||
|
|
||||||
/* Return a static string naming the type of filesystem that the file PATH,
|
|
||||||
described by STATP, is on.
|
|
||||||
RELPATH is the file name relative to the current directory.
|
|
||||||
Return "unknown" if its filesystem type is unknown. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
filesystem_type (const struct stat *statp, const char *path)
|
|
||||||
{
|
|
||||||
static char *current_fstype = NULL;
|
|
||||||
static dev_t current_dev;
|
|
||||||
|
|
||||||
if (current_fstype != NULL)
|
|
||||||
{
|
|
||||||
if (fstype_known && statp->st_dev == current_dev)
|
|
||||||
return current_fstype; /* Cached value. */
|
|
||||||
free (current_fstype);
|
|
||||||
}
|
|
||||||
current_dev = statp->st_dev;
|
|
||||||
current_fstype = filesystem_type_uncached (statp, path);
|
|
||||||
return current_fstype;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
set_fstype_devno(struct mount_entry *p)
|
|
||||||
{
|
|
||||||
struct stat stbuf;
|
|
||||||
|
|
||||||
if (p->me_dev == (dev_t)-1)
|
|
||||||
{
|
|
||||||
if (0 == (options.xstat)(p->me_mountdir, &stbuf))
|
|
||||||
{
|
|
||||||
p->me_dev = stbuf.st_dev;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0; /* not needed */
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mount_entry *
|
|
||||||
must_read_fs_list(bool need_fs_type)
|
|
||||||
{
|
|
||||||
struct mount_entry *entries = read_file_system_list(need_fs_type);
|
|
||||||
if (NULL == entries)
|
|
||||||
{
|
|
||||||
/* We cannot determine for sure which file we were trying to
|
|
||||||
* use because gnulib has extracted all that stuff away.
|
|
||||||
* Hence we cannot issue a specific error message here.
|
|
||||||
*/
|
|
||||||
error(1, 0, "Cannot read mounted filesystem list");
|
|
||||||
}
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Return a newly allocated string naming the type of filesystem that the
|
|
||||||
file PATH, described by STATP, is on.
|
|
||||||
RELPATH is the file name relative to the current directory.
|
|
||||||
Return "unknown" if its filesystem type is unknown. */
|
|
||||||
|
|
||||||
static char *
|
|
||||||
filesystem_type_uncached (const struct stat *statp, const char *path)
|
|
||||||
{
|
|
||||||
struct mount_entry *entries, *entry;
|
|
||||||
char *type;
|
|
||||||
|
|
||||||
#ifdef AFS
|
|
||||||
if (in_afs(path))
|
|
||||||
{
|
|
||||||
fstype_known = 1;
|
|
||||||
return xstrdup("afs");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
entries = must_read_fs_list(true);
|
|
||||||
for (type=NULL, entry=entries; entry; entry=entry->me_next)
|
|
||||||
{
|
|
||||||
#ifdef MNTTYPE_IGNORE
|
|
||||||
if (!strcmp (entry->me_type, MNTTYPE_IGNORE))
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
set_fstype_devno(entry);
|
|
||||||
if (entry->me_dev == statp->st_dev)
|
|
||||||
{
|
|
||||||
type = xstrdup(entry->me_type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free_file_system_list(entries);
|
|
||||||
|
|
||||||
/* Don't cache unknown values. */
|
|
||||||
fstype_known = (type != NULL);
|
|
||||||
|
|
||||||
return type ? type : xstrdup(_("unknown"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char *
|
|
||||||
get_mounted_filesystems (void)
|
|
||||||
{
|
|
||||||
char *result = NULL;
|
|
||||||
size_t alloc_size = 0u;
|
|
||||||
size_t used = 0u;
|
|
||||||
struct mount_entry *entries, *entry;
|
|
||||||
|
|
||||||
entries = must_read_fs_list(false);
|
|
||||||
for (entry=entries; entry; entry=entry->me_next)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
#ifdef MNTTYPE_IGNORE
|
|
||||||
if (!strcmp (entry->me_type, MNTTYPE_IGNORE))
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
set_fstype_devno(entry);
|
|
||||||
|
|
||||||
len = strlen(entry->me_mountdir) + 1;
|
|
||||||
result = extendbuf(result, used+len, &alloc_size);
|
|
||||||
strcpy(&result[used], entry->me_mountdir);
|
|
||||||
used += len; /* len already includes one for the \0 */
|
|
||||||
}
|
|
||||||
|
|
||||||
free_file_system_list(entries);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dev_t *
|
|
||||||
get_mounted_devices (size_t *n)
|
|
||||||
{
|
|
||||||
size_t alloc_size = 0u;
|
|
||||||
size_t used = 0u;
|
|
||||||
struct mount_entry *entries, *entry;
|
|
||||||
dev_t *result = NULL;
|
|
||||||
|
|
||||||
/* Use read_file_system_list() rather than must_read_fs_list()
|
|
||||||
* because on some system this is always called at startup,
|
|
||||||
* and find should only exit fatally if it needs to use the
|
|
||||||
* result of this operation. If we can't get the fs list
|
|
||||||
* but we never need the information, there is no need to fail.
|
|
||||||
*/
|
|
||||||
for (entry = entries = read_file_system_list(false);
|
|
||||||
entry;
|
|
||||||
entry = entry->me_next)
|
|
||||||
{
|
|
||||||
result = extendbuf(result, sizeof(dev_t)*(used+1), &alloc_size);
|
|
||||||
set_fstype_devno(entry);
|
|
||||||
result[used] = entry->me_dev;
|
|
||||||
++used;
|
|
||||||
}
|
|
||||||
free_file_system_list(entries);
|
|
||||||
*n = used;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,495 +0,0 @@
|
|||||||
/* tree.c -- helper functions to build and evaluate the expression tree.
|
|
||||||
Copyright (C) 1990, 91, 92, 93, 94, 2000, 2001, 2003, 2004, 2005, 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
#include "../gnulib/lib/xalloc.h"
|
|
||||||
|
|
||||||
#if ENABLE_NLS
|
|
||||||
# include <libintl.h>
|
|
||||||
# define _(Text) gettext (Text)
|
|
||||||
#else
|
|
||||||
# define _(Text) Text
|
|
||||||
#endif
|
|
||||||
#ifdef gettext_noop
|
|
||||||
# define N_(String) gettext_noop (String)
|
|
||||||
#else
|
|
||||||
/* See locate.c for explanation as to why not use (String) */
|
|
||||||
# define N_(String) String
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct predicate *scan_rest PARAMS((struct predicate **input,
|
|
||||||
struct predicate *head,
|
|
||||||
short int prev_prec));
|
|
||||||
static void merge_pred PARAMS((struct predicate *beg_list, struct predicate *end_list, struct predicate **last_p));
|
|
||||||
static struct predicate *set_new_parent PARAMS((struct predicate *curr, enum predicate_precedence high_prec, struct predicate **prevp));
|
|
||||||
|
|
||||||
/* Return a pointer to a tree that represents the
|
|
||||||
expression prior to non-unary operator *INPUT.
|
|
||||||
Set *INPUT to point at the next input predicate node.
|
|
||||||
|
|
||||||
Only accepts the following:
|
|
||||||
|
|
||||||
<primary>
|
|
||||||
expression [operators of higher precedence]
|
|
||||||
<uni_op><primary>
|
|
||||||
(arbitrary expression)
|
|
||||||
<uni_op>(arbitrary expression)
|
|
||||||
|
|
||||||
In other words, you can not start out with a bi_op or close_paren.
|
|
||||||
|
|
||||||
If the following operator (if any) is of a higher precedence than
|
|
||||||
PREV_PREC, the expression just nabbed is part of a following
|
|
||||||
expression, which really is the expression that should be handed to
|
|
||||||
our caller, so get_expr recurses. */
|
|
||||||
|
|
||||||
struct predicate *
|
|
||||||
get_expr (struct predicate **input, short int prev_prec)
|
|
||||||
{
|
|
||||||
struct predicate *next = NULL;
|
|
||||||
|
|
||||||
if (*input == NULL)
|
|
||||||
error (1, 0, _("invalid expression"));
|
|
||||||
|
|
||||||
switch ((*input)->p_type)
|
|
||||||
{
|
|
||||||
case NO_TYPE:
|
|
||||||
error (1, 0, _("invalid expression"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BI_OP:
|
|
||||||
error (1, 0, _("invalid expression; you have used a binary operator with nothing before it."));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLOSE_PAREN:
|
|
||||||
error (1, 0, _("invalid expression; you have too many ')'"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRIMARY_TYPE:
|
|
||||||
next = *input;
|
|
||||||
*input = (*input)->pred_next;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UNI_OP:
|
|
||||||
next = *input;
|
|
||||||
*input = (*input)->pred_next;
|
|
||||||
next->pred_right = get_expr (input, NEGATE_PREC);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPEN_PAREN:
|
|
||||||
*input = (*input)->pred_next;
|
|
||||||
next = get_expr (input, NO_PREC);
|
|
||||||
if ((*input == NULL)
|
|
||||||
|| ((*input)->p_type != CLOSE_PAREN))
|
|
||||||
error (1, 0, _("invalid expression; I was expecting to find a ')' somewhere but did not see one."));
|
|
||||||
*input = (*input)->pred_next; /* move over close */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
error (1, 0, _("oops -- invalid expression type!"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We now have the first expression and are positioned to check
|
|
||||||
out the next operator. If NULL, all done. Otherwise, if
|
|
||||||
PREV_PREC < the current node precedence, we must continue;
|
|
||||||
the expression we just nabbed is more tightly bound to the
|
|
||||||
following expression than to the previous one. */
|
|
||||||
if (*input == NULL)
|
|
||||||
return (next);
|
|
||||||
if ((int) (*input)->p_prec > (int) prev_prec)
|
|
||||||
{
|
|
||||||
next = scan_rest (input, next, prev_prec);
|
|
||||||
if (next == NULL)
|
|
||||||
error (1, 0, _("invalid expression"));
|
|
||||||
}
|
|
||||||
return (next);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scan across the remainder of a predicate input list starting
|
|
||||||
at *INPUT, building the rest of the expression tree to return.
|
|
||||||
Stop at the first close parenthesis or the end of the input list.
|
|
||||||
Assumes that get_expr has been called to nab the first element
|
|
||||||
of the expression tree.
|
|
||||||
|
|
||||||
*INPUT points to the current input predicate list element.
|
|
||||||
It is updated as we move along the list to point to the
|
|
||||||
terminating input element.
|
|
||||||
HEAD points to the predicate element that was obtained
|
|
||||||
by the call to get_expr.
|
|
||||||
PREV_PREC is the precedence of the previous predicate element. */
|
|
||||||
|
|
||||||
static struct predicate *
|
|
||||||
scan_rest (struct predicate **input,
|
|
||||||
struct predicate *head,
|
|
||||||
short int prev_prec)
|
|
||||||
{
|
|
||||||
struct predicate *tree; /* The new tree we are building. */
|
|
||||||
|
|
||||||
if ((*input == NULL) || ((*input)->p_type == CLOSE_PAREN))
|
|
||||||
return (NULL);
|
|
||||||
tree = head;
|
|
||||||
while ((*input != NULL) && ((int) (*input)->p_prec > (int) prev_prec))
|
|
||||||
{
|
|
||||||
switch ((*input)->p_type)
|
|
||||||
{
|
|
||||||
case NO_TYPE:
|
|
||||||
case PRIMARY_TYPE:
|
|
||||||
case UNI_OP:
|
|
||||||
case OPEN_PAREN:
|
|
||||||
/* I'm not sure how we get here, so it is not obvious what
|
|
||||||
* sort of mistakes might give rise to this condition.
|
|
||||||
*/
|
|
||||||
error (1, 0, _("invalid expression"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BI_OP:
|
|
||||||
(*input)->pred_left = tree;
|
|
||||||
tree = *input;
|
|
||||||
*input = (*input)->pred_next;
|
|
||||||
tree->pred_right = get_expr (input, tree->p_prec);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLOSE_PAREN:
|
|
||||||
return tree;
|
|
||||||
|
|
||||||
default:
|
|
||||||
error (1, 0,
|
|
||||||
_("oops -- invalid expression type (%d)!"),
|
|
||||||
(int)(*input)->p_type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Optimize the ordering of the predicates in the tree. Rearrange
|
|
||||||
them to minimize work. Strategies:
|
|
||||||
* Evaluate predicates that don't need inode information first;
|
|
||||||
the predicates are divided into 1 or more groups separated by
|
|
||||||
predicates (if any) which have "side effects", such as printing.
|
|
||||||
The grouping implements the partial ordering on predicates which
|
|
||||||
those with side effects impose.
|
|
||||||
|
|
||||||
* Place -name, -iname, -path, -ipath, -regex and -iregex at the front
|
|
||||||
of a group, with -name, -iname, -path and -ipath ahead of
|
|
||||||
-regex and -iregex. Predicates which are moved to the front
|
|
||||||
of a group by definition do not have side effects. Both
|
|
||||||
-regex and -iregex both use pred_regex.
|
|
||||||
|
|
||||||
This routine "normalizes" the predicate tree by ensuring that
|
|
||||||
all expression predicates have AND (or OR or COMMA) parent nodes
|
|
||||||
which are linked along the left edge of the expression tree.
|
|
||||||
This makes manipulation of subtrees easier.
|
|
||||||
|
|
||||||
EVAL_TREEP points to the root pointer of the predicate tree
|
|
||||||
to be rearranged. opt_expr may return a new root pointer there.
|
|
||||||
Return true if the tree contains side effects, false if not. */
|
|
||||||
|
|
||||||
boolean
|
|
||||||
opt_expr (struct predicate **eval_treep)
|
|
||||||
{
|
|
||||||
/* List of -name and -path predicates to move. */
|
|
||||||
struct predicate *name_list = NULL;
|
|
||||||
struct predicate *end_name_list = NULL;
|
|
||||||
/* List of -regex predicates to move. */
|
|
||||||
struct predicate *regex_list = NULL;
|
|
||||||
struct predicate *end_regex_list = NULL;
|
|
||||||
struct predicate *curr;
|
|
||||||
struct predicate **prevp; /* Address of `curr' node. */
|
|
||||||
struct predicate **last_sidep; /* Last predicate with side effects. */
|
|
||||||
PRED_FUNC pred_func;
|
|
||||||
enum predicate_type p_type;
|
|
||||||
boolean has_side_effects = false; /* Return value. */
|
|
||||||
enum predicate_precedence prev_prec, /* precedence of last BI_OP in branch */
|
|
||||||
biop_prec; /* topmost BI_OP precedence in branch */
|
|
||||||
|
|
||||||
|
|
||||||
if (eval_treep == NULL || *eval_treep == NULL)
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
/* Set up to normalize tree as a left-linked list of ANDs or ORs.
|
|
||||||
Set `curr' to the leftmost node, `prevp' to its address, and
|
|
||||||
`pred_func' to the predicate type of its parent. */
|
|
||||||
prevp = eval_treep;
|
|
||||||
prev_prec = AND_PREC;
|
|
||||||
curr = *prevp;
|
|
||||||
while (curr->pred_left != NULL)
|
|
||||||
{
|
|
||||||
prevp = &curr->pred_left;
|
|
||||||
prev_prec = curr->p_prec; /* must be a BI_OP */
|
|
||||||
curr = curr->pred_left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Link in the appropriate BI_OP for the last expression, if needed. */
|
|
||||||
if (curr->p_type != BI_OP)
|
|
||||||
set_new_parent (curr, prev_prec, prevp);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
/* Normalized tree. */
|
|
||||||
fprintf (stderr, "Normalized Eval Tree:\n");
|
|
||||||
print_tree (stderr, *eval_treep, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Rearrange the predicates. */
|
|
||||||
prevp = eval_treep;
|
|
||||||
biop_prec = NO_PREC; /* not COMMA_PREC */
|
|
||||||
if ((*prevp) && (*prevp)->p_type == BI_OP)
|
|
||||||
biop_prec = (*prevp)->p_prec;
|
|
||||||
while ((curr = *prevp) != NULL)
|
|
||||||
{
|
|
||||||
/* If there is a BI_OP of different precedence from the first
|
|
||||||
in the pred_left chain, create a new parent of the
|
|
||||||
original precedence, link the new parent to the left of the
|
|
||||||
previous and link CURR to the right of the new parent.
|
|
||||||
This preserves the precedence of expressions in the tree
|
|
||||||
in case we rearrange them. */
|
|
||||||
if (curr->p_type == BI_OP)
|
|
||||||
{
|
|
||||||
if (curr->p_prec != biop_prec)
|
|
||||||
curr = set_new_parent(curr, biop_prec, prevp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See which predicate type we have. */
|
|
||||||
p_type = curr->pred_right->p_type;
|
|
||||||
pred_func = curr->pred_right->pred_func;
|
|
||||||
|
|
||||||
switch (p_type)
|
|
||||||
{
|
|
||||||
case NO_TYPE:
|
|
||||||
case PRIMARY_TYPE:
|
|
||||||
/* Don't rearrange the arguments of the comma operator, it is
|
|
||||||
not commutative. */
|
|
||||||
if (biop_prec == COMMA_PREC)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* If it's one of our special primaries, move it to the
|
|
||||||
front of the list for that primary. */
|
|
||||||
if (pred_func == pred_name || pred_func == pred_path ||
|
|
||||||
pred_func == pred_iname || pred_func == pred_ipath)
|
|
||||||
{
|
|
||||||
*prevp = curr->pred_left;
|
|
||||||
curr->pred_left = name_list;
|
|
||||||
name_list = curr;
|
|
||||||
|
|
||||||
if (end_name_list == NULL)
|
|
||||||
end_name_list = curr;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pred_func == pred_regex)
|
|
||||||
{
|
|
||||||
*prevp = curr->pred_left;
|
|
||||||
curr->pred_left = regex_list;
|
|
||||||
regex_list = curr;
|
|
||||||
|
|
||||||
if (end_regex_list == NULL)
|
|
||||||
end_regex_list = curr;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UNI_OP:
|
|
||||||
/* For NOT, check the expression trees below the NOT. */
|
|
||||||
curr->pred_right->side_effects
|
|
||||||
= opt_expr (&curr->pred_right->pred_right);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BI_OP:
|
|
||||||
/* For nested AND or OR, recurse (AND/OR form layers on the left of
|
|
||||||
the tree), and continue scanning this level of AND or OR. */
|
|
||||||
curr->pred_right->side_effects = opt_expr (&curr->pred_right);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* At this point, get_expr and scan_rest have already removed
|
|
||||||
all of the user's parentheses. */
|
|
||||||
|
|
||||||
default:
|
|
||||||
error (1, 0, _("oops -- invalid expression type!"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curr->pred_right->side_effects == true)
|
|
||||||
{
|
|
||||||
last_sidep = prevp;
|
|
||||||
|
|
||||||
/* Incorporate lists and reset list pointers for this group. */
|
|
||||||
if (name_list != NULL)
|
|
||||||
{
|
|
||||||
merge_pred (name_list, end_name_list, last_sidep);
|
|
||||||
name_list = end_name_list = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (regex_list != NULL)
|
|
||||||
{
|
|
||||||
merge_pred (regex_list, end_regex_list, last_sidep);
|
|
||||||
regex_list = end_regex_list = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
has_side_effects = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
prevp = &curr->pred_left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do final list merges. */
|
|
||||||
last_sidep = prevp;
|
|
||||||
if (name_list != NULL)
|
|
||||||
merge_pred (name_list, end_name_list, last_sidep);
|
|
||||||
if (regex_list != NULL)
|
|
||||||
merge_pred (regex_list, end_regex_list, last_sidep);
|
|
||||||
|
|
||||||
return (has_side_effects);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Link in a new parent BI_OP node for CURR, at *PREVP, with precedence
|
|
||||||
HIGH_PREC. */
|
|
||||||
|
|
||||||
static struct predicate *
|
|
||||||
set_new_parent (struct predicate *curr, enum predicate_precedence high_prec, struct predicate **prevp)
|
|
||||||
{
|
|
||||||
struct predicate *new_parent;
|
|
||||||
|
|
||||||
new_parent = (struct predicate *) xmalloc (sizeof (struct predicate));
|
|
||||||
new_parent->p_type = BI_OP;
|
|
||||||
new_parent->p_prec = high_prec;
|
|
||||||
new_parent->need_stat = false;
|
|
||||||
new_parent->need_type = false;
|
|
||||||
|
|
||||||
switch (high_prec)
|
|
||||||
{
|
|
||||||
case COMMA_PREC:
|
|
||||||
new_parent->pred_func = pred_comma;
|
|
||||||
break;
|
|
||||||
case OR_PREC:
|
|
||||||
new_parent->pred_func = pred_or;
|
|
||||||
break;
|
|
||||||
case AND_PREC:
|
|
||||||
new_parent->pred_func = pred_and;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
; /* empty */
|
|
||||||
}
|
|
||||||
|
|
||||||
new_parent->side_effects = false;
|
|
||||||
new_parent->no_default_print = false;
|
|
||||||
new_parent->args.str = NULL;
|
|
||||||
new_parent->pred_next = NULL;
|
|
||||||
|
|
||||||
/* Link in new_parent.
|
|
||||||
Pushes rest of left branch down 1 level to new_parent->pred_right. */
|
|
||||||
new_parent->pred_left = NULL;
|
|
||||||
new_parent->pred_right = curr;
|
|
||||||
*prevp = new_parent;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
new_parent->p_name = (char *) find_pred_name (new_parent->pred_func);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
return (new_parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Merge the predicate list that starts at BEG_LIST and ends at END_LIST
|
|
||||||
into the tree at LAST_P. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
merge_pred (struct predicate *beg_list, struct predicate *end_list, struct predicate **last_p)
|
|
||||||
{
|
|
||||||
end_list->pred_left = *last_p;
|
|
||||||
*last_p = beg_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the first node in expression tree TREE that requires
|
|
||||||
a stat call and mark the operator above it as needing a stat
|
|
||||||
before calling the node. Since the expression precedences
|
|
||||||
are represented in the tree, some preds that need stat may not
|
|
||||||
get executed (because the expression value is determined earlier.)
|
|
||||||
So every expression needing stat must be marked as such, not just
|
|
||||||
the earliest, to be sure to obtain the stat. This still guarantees
|
|
||||||
that a stat is made as late as possible. Return true if the top node
|
|
||||||
in TREE requires a stat, false if not. */
|
|
||||||
|
|
||||||
boolean
|
|
||||||
mark_stat (struct predicate *tree)
|
|
||||||
{
|
|
||||||
/* The tree is executed in-order, so walk this way (apologies to Aerosmith)
|
|
||||||
to find the first predicate for which the stat is needed. */
|
|
||||||
switch (tree->p_type)
|
|
||||||
{
|
|
||||||
case NO_TYPE:
|
|
||||||
case PRIMARY_TYPE:
|
|
||||||
return tree->need_stat;
|
|
||||||
|
|
||||||
case UNI_OP:
|
|
||||||
if (mark_stat (tree->pred_right))
|
|
||||||
tree->need_stat = true;
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
case BI_OP:
|
|
||||||
/* ANDs and ORs are linked along ->left ending in NULL. */
|
|
||||||
if (tree->pred_left != NULL)
|
|
||||||
mark_stat (tree->pred_left);
|
|
||||||
|
|
||||||
if (mark_stat (tree->pred_right))
|
|
||||||
tree->need_stat = true;
|
|
||||||
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
default:
|
|
||||||
error (1, 0, _("oops -- invalid expression type in mark_stat!"));
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the first node in expression tree TREE that we will
|
|
||||||
need to know the file type, if any. Operates in the same
|
|
||||||
was as mark_stat().
|
|
||||||
*/
|
|
||||||
boolean
|
|
||||||
mark_type (struct predicate *tree)
|
|
||||||
{
|
|
||||||
/* The tree is executed in-order, so walk this way (apologies to Aerosmith)
|
|
||||||
to find the first predicate for which the type information is needed. */
|
|
||||||
switch (tree->p_type)
|
|
||||||
{
|
|
||||||
case NO_TYPE:
|
|
||||||
case PRIMARY_TYPE:
|
|
||||||
return tree->need_type;
|
|
||||||
|
|
||||||
case UNI_OP:
|
|
||||||
if (mark_type (tree->pred_right))
|
|
||||||
tree->need_type = true;
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case BI_OP:
|
|
||||||
/* ANDs and ORs are linked along ->left ending in NULL. */
|
|
||||||
if (tree->pred_left != NULL)
|
|
||||||
mark_type (tree->pred_left);
|
|
||||||
|
|
||||||
if (mark_type (tree->pred_right))
|
|
||||||
tree->need_type = true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
default:
|
|
||||||
error (1, 0, _("oops -- invalid expression type in mark_type!"));
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
/* util.c -- functions for initializing new tree elements, and other things.
|
|
||||||
Copyright (C) 1990, 91, 92, 93, 94, 2000, 2001, 2003, 2004, 2005, 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
#include "xalloc.h"
|
|
||||||
|
|
||||||
#if ENABLE_NLS
|
|
||||||
# include <libintl.h>
|
|
||||||
# define _(Text) gettext (Text)
|
|
||||||
#else
|
|
||||||
# define _(Text) Text
|
|
||||||
#endif
|
|
||||||
#ifdef gettext_noop
|
|
||||||
# define N_(String) gettext_noop (String)
|
|
||||||
#else
|
|
||||||
/* See locate.c for explanation as to why not use (String) */
|
|
||||||
# define N_(String) String
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* Return a pointer to a new predicate structure, which has been
|
|
||||||
linked in as the last one in the predicates list.
|
|
||||||
|
|
||||||
Set `predicates' to point to the start of the predicates list.
|
|
||||||
Set `last_pred' to point to the new last predicate in the list.
|
|
||||||
|
|
||||||
Set all cells in the new structure to the default values. */
|
|
||||||
|
|
||||||
struct predicate *
|
|
||||||
get_new_pred (const struct parser_table *entry)
|
|
||||||
{
|
|
||||||
register struct predicate *new_pred;
|
|
||||||
(void) entry;
|
|
||||||
|
|
||||||
/* Options should not be turned into predicates. */
|
|
||||||
assert(entry->type != ARG_OPTION);
|
|
||||||
assert(entry->type != ARG_POSITIONAL_OPTION);
|
|
||||||
|
|
||||||
if (predicates == NULL)
|
|
||||||
{
|
|
||||||
predicates = (struct predicate *)
|
|
||||||
xmalloc (sizeof (struct predicate));
|
|
||||||
last_pred = predicates;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new_pred = (struct predicate *) xmalloc (sizeof (struct predicate));
|
|
||||||
last_pred->pred_next = new_pred;
|
|
||||||
last_pred = new_pred;
|
|
||||||
}
|
|
||||||
last_pred->parser_entry = entry;
|
|
||||||
last_pred->pred_func = NULL;
|
|
||||||
#ifdef DEBUG
|
|
||||||
last_pred->p_name = NULL;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
last_pred->p_type = NO_TYPE;
|
|
||||||
last_pred->p_prec = NO_PREC;
|
|
||||||
last_pred->side_effects = false;
|
|
||||||
last_pred->no_default_print = false;
|
|
||||||
last_pred->need_stat = true;
|
|
||||||
last_pred->need_type = true;
|
|
||||||
last_pred->args.str = NULL;
|
|
||||||
last_pred->pred_next = NULL;
|
|
||||||
last_pred->pred_left = NULL;
|
|
||||||
last_pred->pred_right = NULL;
|
|
||||||
return (last_pred);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a pointer to a new predicate, with operator check.
|
|
||||||
Like get_new_pred, but it checks to make sure that the previous
|
|
||||||
predicate is an operator. If it isn't, the AND operator is inserted. */
|
|
||||||
|
|
||||||
struct predicate *
|
|
||||||
get_new_pred_chk_op (const struct parser_table *entry)
|
|
||||||
{
|
|
||||||
struct predicate *new_pred;
|
|
||||||
static const struct parser_table *entry_and = NULL;
|
|
||||||
|
|
||||||
/* Locate the entry in the parser table for the "and" operator */
|
|
||||||
if (NULL == entry_and)
|
|
||||||
entry_and = find_parser("and");
|
|
||||||
|
|
||||||
/* Check that it's actually there. If not, that is a bug.*/
|
|
||||||
assert(entry_and != NULL);
|
|
||||||
|
|
||||||
if (last_pred)
|
|
||||||
switch (last_pred->p_type)
|
|
||||||
{
|
|
||||||
case NO_TYPE:
|
|
||||||
error (1, 0, _("oops -- invalid default insertion of and!"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRIMARY_TYPE:
|
|
||||||
case CLOSE_PAREN:
|
|
||||||
/* We need to interpose the and operator. */
|
|
||||||
new_pred = get_new_pred (entry_and);
|
|
||||||
new_pred->pred_func = pred_and;
|
|
||||||
#ifdef DEBUG
|
|
||||||
new_pred->p_name = find_pred_name (pred_and);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
new_pred->p_type = BI_OP;
|
|
||||||
new_pred->p_prec = AND_PREC;
|
|
||||||
new_pred->need_stat = false;
|
|
||||||
new_pred->need_type = false;
|
|
||||||
new_pred->args.str = NULL;
|
|
||||||
new_pred->side_effects = false;
|
|
||||||
new_pred->no_default_print = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_pred = get_new_pred (entry);
|
|
||||||
new_pred->parser_entry = entry;
|
|
||||||
return new_pred;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a primary of predicate type PRED_FUNC (described by ENTRY) to the predicate input list.
|
|
||||||
|
|
||||||
Return a pointer to the predicate node just inserted.
|
|
||||||
|
|
||||||
Fills in the following cells of the new predicate node:
|
|
||||||
|
|
||||||
pred_func PRED_FUNC
|
|
||||||
args(.str) NULL
|
|
||||||
p_type PRIMARY_TYPE
|
|
||||||
p_prec NO_PREC
|
|
||||||
|
|
||||||
Other cells that need to be filled in are defaulted by
|
|
||||||
get_new_pred_chk_op, which is used to insure that the prior node is
|
|
||||||
either not there at all (we are the very first node) or is an
|
|
||||||
operator. */
|
|
||||||
|
|
||||||
struct predicate *
|
|
||||||
insert_primary_withpred (const struct parser_table *entry, PRED_FUNC pred_func)
|
|
||||||
{
|
|
||||||
struct predicate *new_pred;
|
|
||||||
|
|
||||||
new_pred = get_new_pred_chk_op (entry);
|
|
||||||
new_pred->pred_func = pred_func;
|
|
||||||
#ifdef DEBUG
|
|
||||||
new_pred->p_name = entry->parser_name;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
new_pred->args.str = NULL;
|
|
||||||
new_pred->p_type = PRIMARY_TYPE;
|
|
||||||
new_pred->p_prec = NO_PREC;
|
|
||||||
return new_pred;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a primary described by ENTRY to the predicate input list.
|
|
||||||
|
|
||||||
Return a pointer to the predicate node just inserted.
|
|
||||||
|
|
||||||
Fills in the following cells of the new predicate node:
|
|
||||||
|
|
||||||
pred_func PRED_FUNC
|
|
||||||
args(.str) NULL
|
|
||||||
p_type PRIMARY_TYPE
|
|
||||||
p_prec NO_PREC
|
|
||||||
|
|
||||||
Other cells that need to be filled in are defaulted by
|
|
||||||
get_new_pred_chk_op, which is used to insure that the prior node is
|
|
||||||
either not there at all (we are the very first node) or is an
|
|
||||||
operator. */
|
|
||||||
struct predicate *
|
|
||||||
insert_primary (const struct parser_table *entry)
|
|
||||||
{
|
|
||||||
assert(entry->pred_func != NULL);
|
|
||||||
return insert_primary_withpred(entry, entry->pred_func);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
usage (char *msg)
|
|
||||||
{
|
|
||||||
if (msg)
|
|
||||||
fprintf (stderr, "%s: %s\n", program_name, msg);
|
|
||||||
fprintf (stderr, _("\
|
|
||||||
Usage: %s [-H] [-L] [-P] [path...] [expression]\n"), program_name);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#include <config.h>
|
|
||||||
char *version_string = VERSION;
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
resource app_version
|
|
||||||
{
|
|
||||||
major = 4,
|
|
||||||
middle = 2,
|
|
||||||
minor = 33,
|
|
||||||
variety = 5,
|
|
||||||
internal = 0,
|
|
||||||
short_info = "4.2.33",
|
|
||||||
long_info = "4.2.33 ©2008 The Free Software Foundation"
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
SubDir HAIKU_TOP src bin findutils gnulib ;
|
|
||||||
|
|
||||||
SubInclude HAIKU_TOP src bin findutils gnulib lib ;
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
SubDir HAIKU_TOP src bin findutils gnulib lib ;
|
|
||||||
|
|
||||||
SubDirSysHdrs [ FDirName $(SUBDIR) ] ;
|
|
||||||
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ;
|
|
||||||
|
|
||||||
# filter warnings we don't want here
|
|
||||||
TARGET_WARNING_CCFLAGS_$(TARGET_PACKAGING_ARCH)
|
|
||||||
= [ FFilter $(TARGET_WARNING_CCFLAGS_$(TARGET_PACKAGING_ARCH))
|
|
||||||
: -Wall -Wmissing-prototypes -Wsign-compare ] ;
|
|
||||||
|
|
||||||
# set some additional defines
|
|
||||||
{
|
|
||||||
SubDirCcFlags -DHAVE_CONFIG_H ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
StaticLibrary gnulibfindutils.a :
|
|
||||||
areadlink-with-size.c
|
|
||||||
argmatch.c
|
|
||||||
basename.c
|
|
||||||
canonicalize.c
|
|
||||||
closein.c
|
|
||||||
closeout.c
|
|
||||||
close-stream.c
|
|
||||||
dirname.c
|
|
||||||
dup-safer.c
|
|
||||||
error.c
|
|
||||||
exitfail.c
|
|
||||||
filemode.c
|
|
||||||
file-set.c
|
|
||||||
fnmatch.c
|
|
||||||
fopen-safer.c
|
|
||||||
fpending.c
|
|
||||||
freadahead.c
|
|
||||||
getcwd.c
|
|
||||||
hash.c
|
|
||||||
hash-pjw.c
|
|
||||||
hash-triple.c
|
|
||||||
human.c
|
|
||||||
idcache.c
|
|
||||||
localcharset.c
|
|
||||||
modechange.c
|
|
||||||
mountlist.c
|
|
||||||
quote.c
|
|
||||||
quotearg.c
|
|
||||||
regex.c
|
|
||||||
same.c
|
|
||||||
stripslash.c
|
|
||||||
strndup.c
|
|
||||||
xalloc-die.c
|
|
||||||
xgetcwd.c
|
|
||||||
xmalloc.c
|
|
||||||
xstrndup.c
|
|
||||||
xstrtol-error.c
|
|
||||||
xstrtoumax.c
|
|
||||||
yesno.c
|
|
||||||
;
|
|
||||||
|
|
||||||
#SEARCH on [ FGristFiles version.c ] = [ FDirName $(SUBDIR) $(DOTDOT) find ] ;
|
|
||||||
@@ -1,489 +0,0 @@
|
|||||||
/* alloca.c -- allocate automatically reclaimed memory
|
|
||||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
|
||||||
|
|
||||||
This implementation of the PWB library alloca function,
|
|
||||||
which is used to allocate space off the run-time stack so
|
|
||||||
that it is automatically reclaimed upon procedure exit,
|
|
||||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
|
||||||
J.Otto Tennant <[email protected]> contributed the Cray support.
|
|
||||||
|
|
||||||
There are some preprocessor constants that can
|
|
||||||
be defined when compiling for your specific system, for
|
|
||||||
improved efficiency; however, the defaults should be okay.
|
|
||||||
|
|
||||||
The general concept of this implementation is to keep
|
|
||||||
track of all alloca-allocated blocks, and reclaim any
|
|
||||||
that are found to be deeper in the stack than the current
|
|
||||||
invocation. This heuristic does not reclaim storage as
|
|
||||||
soon as it becomes invalid, but it will do so eventually.
|
|
||||||
|
|
||||||
As a special case, alloca(0) reclaims storage without
|
|
||||||
allocating any. It is a good idea to use alloca(0) in
|
|
||||||
your main control loop, etc. to force garbage collection. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <alloca.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef emacs
|
|
||||||
# include "lisp.h"
|
|
||||||
# include "blockinput.h"
|
|
||||||
# ifdef EMACS_FREE
|
|
||||||
# undef free
|
|
||||||
# define free EMACS_FREE
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define memory_full() abort ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If compiling with GCC 2, this file's not needed. */
|
|
||||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
|
||||||
|
|
||||||
/* If someone has defined alloca as a macro,
|
|
||||||
there must be some other way alloca is supposed to work. */
|
|
||||||
# ifndef alloca
|
|
||||||
|
|
||||||
# ifdef emacs
|
|
||||||
# ifdef static
|
|
||||||
/* actually, only want this if static is defined as ""
|
|
||||||
-- this is for usg, in which emacs must undefine static
|
|
||||||
in order to make unexec workable
|
|
||||||
*/
|
|
||||||
# ifndef STACK_DIRECTION
|
|
||||||
you
|
|
||||||
lose
|
|
||||||
-- must know STACK_DIRECTION at compile-time
|
|
||||||
/* Using #error here is not wise since this file should work for
|
|
||||||
old and obscure compilers. */
|
|
||||||
# endif /* STACK_DIRECTION undefined */
|
|
||||||
# endif /* static */
|
|
||||||
# endif /* emacs */
|
|
||||||
|
|
||||||
/* If your stack is a linked list of frames, you have to
|
|
||||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
|
||||||
|
|
||||||
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
|
||||||
long i00afunc ();
|
|
||||||
# define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
|
||||||
# else
|
|
||||||
# define ADDRESS_FUNCTION(arg) &(arg)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Define STACK_DIRECTION if you know the direction of stack
|
|
||||||
growth for your system; otherwise it will be automatically
|
|
||||||
deduced at run-time.
|
|
||||||
|
|
||||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
|
||||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
|
||||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
|
||||||
|
|
||||||
# ifndef STACK_DIRECTION
|
|
||||||
# define STACK_DIRECTION 0 /* Direction unknown. */
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if STACK_DIRECTION != 0
|
|
||||||
|
|
||||||
# define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
|
||||||
|
|
||||||
# else /* STACK_DIRECTION == 0; need run-time code. */
|
|
||||||
|
|
||||||
static int stack_dir; /* 1 or -1 once known. */
|
|
||||||
# define STACK_DIR stack_dir
|
|
||||||
|
|
||||||
static void
|
|
||||||
find_stack_direction (void)
|
|
||||||
{
|
|
||||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
|
||||||
auto char dummy; /* To get stack address. */
|
|
||||||
|
|
||||||
if (addr == NULL)
|
|
||||||
{ /* Initial entry. */
|
|
||||||
addr = ADDRESS_FUNCTION (dummy);
|
|
||||||
|
|
||||||
find_stack_direction (); /* Recurse once. */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Second entry. */
|
|
||||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
|
||||||
stack_dir = 1; /* Stack grew upward. */
|
|
||||||
else
|
|
||||||
stack_dir = -1; /* Stack grew downward. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# endif /* STACK_DIRECTION == 0 */
|
|
||||||
|
|
||||||
/* An "alloca header" is used to:
|
|
||||||
(a) chain together all alloca'ed blocks;
|
|
||||||
(b) keep track of stack depth.
|
|
||||||
|
|
||||||
It is very important that sizeof(header) agree with malloc
|
|
||||||
alignment chunk size. The following default should work okay. */
|
|
||||||
|
|
||||||
# ifndef ALIGN_SIZE
|
|
||||||
# define ALIGN_SIZE sizeof(double)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
typedef union hdr
|
|
||||||
{
|
|
||||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
union hdr *next; /* For chaining headers. */
|
|
||||||
char *deep; /* For stack depth measure. */
|
|
||||||
} h;
|
|
||||||
} header;
|
|
||||||
|
|
||||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
|
||||||
|
|
||||||
/* Return a pointer to at least SIZE bytes of storage,
|
|
||||||
which will be automatically reclaimed upon exit from
|
|
||||||
the procedure that called alloca. Originally, this space
|
|
||||||
was supposed to be taken from the current stack frame of the
|
|
||||||
caller, but that method cannot be made to work for some
|
|
||||||
implementations of C, for example under Gould's UTX/32. */
|
|
||||||
|
|
||||||
void *
|
|
||||||
alloca (size_t size)
|
|
||||||
{
|
|
||||||
auto char probe; /* Probes stack depth: */
|
|
||||||
register char *depth = ADDRESS_FUNCTION (probe);
|
|
||||||
|
|
||||||
# if STACK_DIRECTION == 0
|
|
||||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
|
||||||
find_stack_direction ();
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Reclaim garbage, defined as all alloca'd storage that
|
|
||||||
was allocated from deeper in the stack than currently. */
|
|
||||||
|
|
||||||
{
|
|
||||||
register header *hp; /* Traverses linked list. */
|
|
||||||
|
|
||||||
# ifdef emacs
|
|
||||||
BLOCK_INPUT;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
for (hp = last_alloca_header; hp != NULL;)
|
|
||||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
|
||||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
|
||||||
{
|
|
||||||
register header *np = hp->h.next;
|
|
||||||
|
|
||||||
free (hp); /* Collect garbage. */
|
|
||||||
|
|
||||||
hp = np; /* -> next header. */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break; /* Rest are not deeper. */
|
|
||||||
|
|
||||||
last_alloca_header = hp; /* -> last valid storage. */
|
|
||||||
|
|
||||||
# ifdef emacs
|
|
||||||
UNBLOCK_INPUT;
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
return NULL; /* No allocation required. */
|
|
||||||
|
|
||||||
/* Allocate combined header + user data storage. */
|
|
||||||
|
|
||||||
{
|
|
||||||
/* Address of header. */
|
|
||||||
register header *new;
|
|
||||||
|
|
||||||
size_t combined_size = sizeof (header) + size;
|
|
||||||
if (combined_size < sizeof (header))
|
|
||||||
memory_full ();
|
|
||||||
|
|
||||||
new = malloc (combined_size);
|
|
||||||
|
|
||||||
if (! new)
|
|
||||||
memory_full ();
|
|
||||||
|
|
||||||
new->h.next = last_alloca_header;
|
|
||||||
new->h.deep = depth;
|
|
||||||
|
|
||||||
last_alloca_header = new;
|
|
||||||
|
|
||||||
/* User storage begins just after header. */
|
|
||||||
|
|
||||||
return (void *) (new + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
|
||||||
|
|
||||||
# ifdef DEBUG_I00AFUNC
|
|
||||||
# include <stdio.h>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef CRAY_STACK
|
|
||||||
# define CRAY_STACK
|
|
||||||
# ifndef CRAY2
|
|
||||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
|
||||||
struct stack_control_header
|
|
||||||
{
|
|
||||||
long shgrow:32; /* Number of times stack has grown. */
|
|
||||||
long shaseg:32; /* Size of increments to stack. */
|
|
||||||
long shhwm:32; /* High water mark of stack. */
|
|
||||||
long shsize:32; /* Current size of stack (all segments). */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The stack segment linkage control information occurs at
|
|
||||||
the high-address end of a stack segment. (The stack
|
|
||||||
grows from low addresses to high addresses.) The initial
|
|
||||||
part of the stack segment linkage control information is
|
|
||||||
0200 (octal) words. This provides for register storage
|
|
||||||
for the routine which overflows the stack. */
|
|
||||||
|
|
||||||
struct stack_segment_linkage
|
|
||||||
{
|
|
||||||
long ss[0200]; /* 0200 overflow words. */
|
|
||||||
long sssize:32; /* Number of words in this segment. */
|
|
||||||
long ssbase:32; /* Offset to stack base. */
|
|
||||||
long:32;
|
|
||||||
long sspseg:32; /* Offset to linkage control of previous
|
|
||||||
segment of stack. */
|
|
||||||
long:32;
|
|
||||||
long sstcpt:32; /* Pointer to task common address block. */
|
|
||||||
long sscsnm; /* Private control structure number for
|
|
||||||
microtasking. */
|
|
||||||
long ssusr1; /* Reserved for user. */
|
|
||||||
long ssusr2; /* Reserved for user. */
|
|
||||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
|
||||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
|
||||||
long sscray[7]; /* Reserved for Cray Research. */
|
|
||||||
long ssa0;
|
|
||||||
long ssa1;
|
|
||||||
long ssa2;
|
|
||||||
long ssa3;
|
|
||||||
long ssa4;
|
|
||||||
long ssa5;
|
|
||||||
long ssa6;
|
|
||||||
long ssa7;
|
|
||||||
long sss0;
|
|
||||||
long sss1;
|
|
||||||
long sss2;
|
|
||||||
long sss3;
|
|
||||||
long sss4;
|
|
||||||
long sss5;
|
|
||||||
long sss6;
|
|
||||||
long sss7;
|
|
||||||
};
|
|
||||||
|
|
||||||
# else /* CRAY2 */
|
|
||||||
/* The following structure defines the vector of words
|
|
||||||
returned by the STKSTAT library routine. */
|
|
||||||
struct stk_stat
|
|
||||||
{
|
|
||||||
long now; /* Current total stack size. */
|
|
||||||
long maxc; /* Amount of contiguous space which would
|
|
||||||
be required to satisfy the maximum
|
|
||||||
stack demand to date. */
|
|
||||||
long high_water; /* Stack high-water mark. */
|
|
||||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
|
||||||
long hits; /* Number of internal buffer hits. */
|
|
||||||
long extends; /* Number of block extensions. */
|
|
||||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
|
||||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
|
||||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
|
||||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
|
||||||
long segments; /* Current number of stack segments. */
|
|
||||||
long maxs; /* Maximum number of stack segments so far. */
|
|
||||||
long pad_size; /* Stack pad size. */
|
|
||||||
long current_address; /* Current stack segment address. */
|
|
||||||
long current_size; /* Current stack segment size. This
|
|
||||||
number is actually corrupted by STKSTAT to
|
|
||||||
include the fifteen word trailer area. */
|
|
||||||
long initial_address; /* Address of initial segment. */
|
|
||||||
long initial_size; /* Size of initial segment. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The following structure describes the data structure which trails
|
|
||||||
any stack segment. I think that the description in 'asdef' is
|
|
||||||
out of date. I only describe the parts that I am sure about. */
|
|
||||||
|
|
||||||
struct stk_trailer
|
|
||||||
{
|
|
||||||
long this_address; /* Address of this block. */
|
|
||||||
long this_size; /* Size of this block (does not include
|
|
||||||
this trailer). */
|
|
||||||
long unknown2;
|
|
||||||
long unknown3;
|
|
||||||
long link; /* Address of trailer block of previous
|
|
||||||
segment. */
|
|
||||||
long unknown5;
|
|
||||||
long unknown6;
|
|
||||||
long unknown7;
|
|
||||||
long unknown8;
|
|
||||||
long unknown9;
|
|
||||||
long unknown10;
|
|
||||||
long unknown11;
|
|
||||||
long unknown12;
|
|
||||||
long unknown13;
|
|
||||||
long unknown14;
|
|
||||||
};
|
|
||||||
|
|
||||||
# endif /* CRAY2 */
|
|
||||||
# endif /* not CRAY_STACK */
|
|
||||||
|
|
||||||
# ifdef CRAY2
|
|
||||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
|
||||||
I doubt that "lint" will like this much. */
|
|
||||||
|
|
||||||
static long
|
|
||||||
i00afunc (long *address)
|
|
||||||
{
|
|
||||||
struct stk_stat status;
|
|
||||||
struct stk_trailer *trailer;
|
|
||||||
long *block, size;
|
|
||||||
long result = 0;
|
|
||||||
|
|
||||||
/* We want to iterate through all of the segments. The first
|
|
||||||
step is to get the stack status structure. We could do this
|
|
||||||
more quickly and more directly, perhaps, by referencing the
|
|
||||||
$LM00 common block, but I know that this works. */
|
|
||||||
|
|
||||||
STKSTAT (&status);
|
|
||||||
|
|
||||||
/* Set up the iteration. */
|
|
||||||
|
|
||||||
trailer = (struct stk_trailer *) (status.current_address
|
|
||||||
+ status.current_size
|
|
||||||
- 15);
|
|
||||||
|
|
||||||
/* There must be at least one stack segment. Therefore it is
|
|
||||||
a fatal error if "trailer" is null. */
|
|
||||||
|
|
||||||
if (trailer == 0)
|
|
||||||
abort ();
|
|
||||||
|
|
||||||
/* Discard segments that do not contain our argument address. */
|
|
||||||
|
|
||||||
while (trailer != 0)
|
|
||||||
{
|
|
||||||
block = (long *) trailer->this_address;
|
|
||||||
size = trailer->this_size;
|
|
||||||
if (block == 0 || size == 0)
|
|
||||||
abort ();
|
|
||||||
trailer = (struct stk_trailer *) trailer->link;
|
|
||||||
if ((block <= address) && (address < (block + size)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the result to the offset in this segment and add the sizes
|
|
||||||
of all predecessor segments. */
|
|
||||||
|
|
||||||
result = address - block;
|
|
||||||
|
|
||||||
if (trailer == 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (trailer->this_size <= 0)
|
|
||||||
abort ();
|
|
||||||
result += trailer->this_size;
|
|
||||||
trailer = (struct stk_trailer *) trailer->link;
|
|
||||||
}
|
|
||||||
while (trailer != 0);
|
|
||||||
|
|
||||||
/* We are done. Note that if you present a bogus address (one
|
|
||||||
not in any segment), you will get a different number back, formed
|
|
||||||
from subtracting the address of the first block. This is probably
|
|
||||||
not what you want. */
|
|
||||||
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
# else /* not CRAY2 */
|
|
||||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
|
||||||
Determine the number of the cell within the stack,
|
|
||||||
given the address of the cell. The purpose of this
|
|
||||||
routine is to linearize, in some sense, stack addresses
|
|
||||||
for alloca. */
|
|
||||||
|
|
||||||
static long
|
|
||||||
i00afunc (long address)
|
|
||||||
{
|
|
||||||
long stkl = 0;
|
|
||||||
|
|
||||||
long size, pseg, this_segment, stack;
|
|
||||||
long result = 0;
|
|
||||||
|
|
||||||
struct stack_segment_linkage *ssptr;
|
|
||||||
|
|
||||||
/* Register B67 contains the address of the end of the
|
|
||||||
current stack segment. If you (as a subprogram) store
|
|
||||||
your registers on the stack and find that you are past
|
|
||||||
the contents of B67, you have overflowed the segment.
|
|
||||||
|
|
||||||
B67 also points to the stack segment linkage control
|
|
||||||
area, which is what we are really interested in. */
|
|
||||||
|
|
||||||
stkl = CRAY_STACKSEG_END ();
|
|
||||||
ssptr = (struct stack_segment_linkage *) stkl;
|
|
||||||
|
|
||||||
/* If one subtracts 'size' from the end of the segment,
|
|
||||||
one has the address of the first word of the segment.
|
|
||||||
|
|
||||||
If this is not the first segment, 'pseg' will be
|
|
||||||
nonzero. */
|
|
||||||
|
|
||||||
pseg = ssptr->sspseg;
|
|
||||||
size = ssptr->sssize;
|
|
||||||
|
|
||||||
this_segment = stkl - size;
|
|
||||||
|
|
||||||
/* It is possible that calling this routine itself caused
|
|
||||||
a stack overflow. Discard stack segments which do not
|
|
||||||
contain the target address. */
|
|
||||||
|
|
||||||
while (!(this_segment <= address && address <= stkl))
|
|
||||||
{
|
|
||||||
# ifdef DEBUG_I00AFUNC
|
|
||||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
|
||||||
# endif
|
|
||||||
if (pseg == 0)
|
|
||||||
break;
|
|
||||||
stkl = stkl - pseg;
|
|
||||||
ssptr = (struct stack_segment_linkage *) stkl;
|
|
||||||
size = ssptr->sssize;
|
|
||||||
pseg = ssptr->sspseg;
|
|
||||||
this_segment = stkl - size;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = address - this_segment;
|
|
||||||
|
|
||||||
/* If you subtract pseg from the current end of the stack,
|
|
||||||
you get the address of the previous stack segment's end.
|
|
||||||
This seems a little convoluted to me, but I'll bet you save
|
|
||||||
a cycle somewhere. */
|
|
||||||
|
|
||||||
while (pseg != 0)
|
|
||||||
{
|
|
||||||
# ifdef DEBUG_I00AFUNC
|
|
||||||
fprintf (stderr, "%011o %011o\n", pseg, size);
|
|
||||||
# endif
|
|
||||||
stkl = stkl - pseg;
|
|
||||||
ssptr = (struct stack_segment_linkage *) stkl;
|
|
||||||
size = ssptr->sssize;
|
|
||||||
pseg = ssptr->sspseg;
|
|
||||||
result += size;
|
|
||||||
}
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
# endif /* not CRAY2 */
|
|
||||||
# endif /* CRAY */
|
|
||||||
|
|
||||||
# endif /* no alloca */
|
|
||||||
#endif /* not GCC version 3 */
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
|
||||||
/* Memory allocation on the stack.
|
|
||||||
|
|
||||||
Copyright (C) 1995, 1999, 2001-2004, 2006-2007 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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
||||||
USA. */
|
|
||||||
|
|
||||||
/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
|
|
||||||
means there is a real alloca function. */
|
|
||||||
#ifndef _GL_ALLOCA_H
|
|
||||||
#define _GL_ALLOCA_H
|
|
||||||
|
|
||||||
/* alloca (N) returns a pointer to N bytes of memory
|
|
||||||
allocated on the stack, which will last until the function returns.
|
|
||||||
Use of alloca should be avoided:
|
|
||||||
- inside arguments of function calls - undefined behaviour,
|
|
||||||
- in inline functions - the allocation may actually last until the
|
|
||||||
calling function returns,
|
|
||||||
- for huge N (say, N >= 65536) - you never know how large (or small)
|
|
||||||
the stack is, and when the stack cannot fulfill the memory allocation
|
|
||||||
request, the program just crashes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef alloca
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define alloca __builtin_alloca
|
|
||||||
# elif defined _AIX
|
|
||||||
# define alloca __alloca
|
|
||||||
# elif defined _MSC_VER
|
|
||||||
# include <malloc.h>
|
|
||||||
# define alloca _alloca
|
|
||||||
# else
|
|
||||||
# include <stddef.h>
|
|
||||||
# ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
# endif
|
|
||||||
void *alloca (size_t);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _GL_ALLOCA_H */
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/* Memory allocation on the stack.
|
|
||||||
|
|
||||||
Copyright (C) 1995, 1999, 2001-2004, 2006-2007 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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
||||||
USA. */
|
|
||||||
|
|
||||||
/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
|
|
||||||
means there is a real alloca function. */
|
|
||||||
#ifndef _GL_ALLOCA_H
|
|
||||||
#define _GL_ALLOCA_H
|
|
||||||
|
|
||||||
/* alloca (N) returns a pointer to N bytes of memory
|
|
||||||
allocated on the stack, which will last until the function returns.
|
|
||||||
Use of alloca should be avoided:
|
|
||||||
- inside arguments of function calls - undefined behaviour,
|
|
||||||
- in inline functions - the allocation may actually last until the
|
|
||||||
calling function returns,
|
|
||||||
- for huge N (say, N >= 65536) - you never know how large (or small)
|
|
||||||
the stack is, and when the stack cannot fulfill the memory allocation
|
|
||||||
request, the program just crashes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef alloca
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define alloca __builtin_alloca
|
|
||||||
# elif defined _AIX
|
|
||||||
# define alloca __alloca
|
|
||||||
# elif defined _MSC_VER
|
|
||||||
# include <malloc.h>
|
|
||||||
# define alloca _alloca
|
|
||||||
# else
|
|
||||||
# include <stddef.h>
|
|
||||||
# ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
# endif
|
|
||||||
void *alloca (size_t);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _GL_ALLOCA_H */
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
/* readlink wrapper to return the link name in malloc'd storage.
|
|
||||||
Unlike xreadlink and xreadlink_with_size, don't ever call exit.
|
|
||||||
|
|
||||||
Copyright (C) 2001, 2003-2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering <[email protected]> */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "areadlink.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX ((size_t) -1)
|
|
||||||
#endif
|
|
||||||
#ifndef SSIZE_MAX
|
|
||||||
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* SYMLINK_MAX is used only for an initial memory-allocation sanity
|
|
||||||
check, so it's OK to guess too small on hosts where there is no
|
|
||||||
arbitrary limit to symbolic link length. */
|
|
||||||
#ifndef SYMLINK_MAX
|
|
||||||
# define SYMLINK_MAX 1024
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX)
|
|
||||||
|
|
||||||
/* Call readlink to get the symbolic link value of FILE.
|
|
||||||
SIZE is a hint as to how long the link is expected to be;
|
|
||||||
typically it is taken from st_size. It need not be correct.
|
|
||||||
Return a pointer to that NUL-terminated string in malloc'd storage.
|
|
||||||
If readlink fails, malloc fails, or if the link value is longer
|
|
||||||
than SSIZE_MAX, return NULL (caller may use errno to diagnose). */
|
|
||||||
|
|
||||||
char *
|
|
||||||
areadlink_with_size (char const *file, size_t size)
|
|
||||||
{
|
|
||||||
/* Some buggy file systems report garbage in st_size. Defend
|
|
||||||
against them by ignoring outlandish st_size values in the initial
|
|
||||||
memory allocation. */
|
|
||||||
size_t symlink_max = SYMLINK_MAX;
|
|
||||||
size_t INITIAL_LIMIT_BOUND = 8 * 1024;
|
|
||||||
size_t initial_limit = (symlink_max < INITIAL_LIMIT_BOUND
|
|
||||||
? symlink_max + 1
|
|
||||||
: INITIAL_LIMIT_BOUND);
|
|
||||||
|
|
||||||
/* The initial buffer size for the link value. */
|
|
||||||
size_t buf_size = size < initial_limit ? size + 1 : initial_limit;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
ssize_t r;
|
|
||||||
size_t link_length;
|
|
||||||
char *buffer = malloc (buf_size);
|
|
||||||
|
|
||||||
if (buffer == NULL)
|
|
||||||
return NULL;
|
|
||||||
r = readlink (file, buffer, buf_size);
|
|
||||||
link_length = r;
|
|
||||||
|
|
||||||
/* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1
|
|
||||||
with errno == ERANGE if the buffer is too small. */
|
|
||||||
if (r < 0 && errno != ERANGE)
|
|
||||||
{
|
|
||||||
int saved_errno = errno;
|
|
||||||
free (buffer);
|
|
||||||
errno = saved_errno;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (link_length < buf_size)
|
|
||||||
{
|
|
||||||
buffer[link_length] = 0;
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
free (buffer);
|
|
||||||
if (buf_size <= MAXSIZE / 2)
|
|
||||||
buf_size *= 2;
|
|
||||||
else if (buf_size < MAXSIZE)
|
|
||||||
buf_size = MAXSIZE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/* Read symbolic links without size limitation.
|
|
||||||
|
|
||||||
Copyright (C) 2001, 2003, 2004, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering <[email protected]> */
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
extern char *areadlink (char const *filename);
|
|
||||||
extern char *areadlink_with_size (char const *filename, size_t size_hint);
|
|
||||||
@@ -1,277 +0,0 @@
|
|||||||
/* argmatch.c -- find a match for a string in an array
|
|
||||||
|
|
||||||
Copyright (C) 1990, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
|
||||||
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by David MacKenzie <[email protected]>
|
|
||||||
Modified by Akim Demaille <[email protected]> */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include "argmatch.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "gettext.h"
|
|
||||||
#define _(msgid) gettext (msgid)
|
|
||||||
|
|
||||||
#include "error.h"
|
|
||||||
#include "quotearg.h"
|
|
||||||
#include "quote.h"
|
|
||||||
|
|
||||||
#if USE_UNLOCKED_IO
|
|
||||||
# include "unlocked-io.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* When reporting an invalid argument, show nonprinting characters
|
|
||||||
by using the quoting style ARGMATCH_QUOTING_STYLE. Do not use
|
|
||||||
literal_quoting_style. */
|
|
||||||
#ifndef ARGMATCH_QUOTING_STYLE
|
|
||||||
# define ARGMATCH_QUOTING_STYLE locale_quoting_style
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Non failing version of argmatch call this function after failing. */
|
|
||||||
#ifndef ARGMATCH_DIE
|
|
||||||
# include "exitfail.h"
|
|
||||||
# define ARGMATCH_DIE exit (exit_failure)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ARGMATCH_DIE_DECL
|
|
||||||
ARGMATCH_DIE_DECL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
__argmatch_die (void)
|
|
||||||
{
|
|
||||||
ARGMATCH_DIE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Used by XARGMATCH and XARGCASEMATCH. See description in argmatch.h.
|
|
||||||
Default to __argmatch_die, but allow caller to change this at run-time. */
|
|
||||||
argmatch_exit_fn argmatch_die = __argmatch_die;
|
|
||||||
|
|
||||||
|
|
||||||
/* If ARG is an unambiguous match for an element of the
|
|
||||||
NULL-terminated array ARGLIST, return the index in ARGLIST
|
|
||||||
of the matched element, else -1 if it does not match any element
|
|
||||||
or -2 if it is ambiguous (is a prefix of more than one element).
|
|
||||||
|
|
||||||
If VALLIST is none null, use it to resolve ambiguities limited to
|
|
||||||
synonyms, i.e., for
|
|
||||||
"yes", "yop" -> 0
|
|
||||||
"no", "nope" -> 1
|
|
||||||
"y" is a valid argument, for `0', and "n" for `1'. */
|
|
||||||
|
|
||||||
ptrdiff_t
|
|
||||||
argmatch (const char *arg, const char *const *arglist,
|
|
||||||
const char *vallist, size_t valsize)
|
|
||||||
{
|
|
||||||
size_t i; /* Temporary index in ARGLIST. */
|
|
||||||
size_t arglen; /* Length of ARG. */
|
|
||||||
ptrdiff_t matchind = -1; /* Index of first nonexact match. */
|
|
||||||
bool ambiguous = false; /* If true, multiple nonexact match(es). */
|
|
||||||
|
|
||||||
arglen = strlen (arg);
|
|
||||||
|
|
||||||
/* Test all elements for either exact match or abbreviated matches. */
|
|
||||||
for (i = 0; arglist[i]; i++)
|
|
||||||
{
|
|
||||||
if (!strncmp (arglist[i], arg, arglen))
|
|
||||||
{
|
|
||||||
if (strlen (arglist[i]) == arglen)
|
|
||||||
/* Exact match found. */
|
|
||||||
return i;
|
|
||||||
else if (matchind == -1)
|
|
||||||
/* First nonexact match found. */
|
|
||||||
matchind = i;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Second nonexact match found. */
|
|
||||||
if (vallist == NULL
|
|
||||||
|| memcmp (vallist + valsize * matchind,
|
|
||||||
vallist + valsize * i, valsize))
|
|
||||||
{
|
|
||||||
/* There is a real ambiguity, or we could not
|
|
||||||
disambiguate. */
|
|
||||||
ambiguous = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ambiguous)
|
|
||||||
return -2;
|
|
||||||
else
|
|
||||||
return matchind;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Error reporting for argmatch.
|
|
||||||
CONTEXT is a description of the type of entity that was being matched.
|
|
||||||
VALUE is the invalid value that was given.
|
|
||||||
PROBLEM is the return value from argmatch. */
|
|
||||||
|
|
||||||
void
|
|
||||||
argmatch_invalid (const char *context, const char *value, ptrdiff_t problem)
|
|
||||||
{
|
|
||||||
char const *format = (problem == -1
|
|
||||||
? _("invalid argument %s for %s")
|
|
||||||
: _("ambiguous argument %s for %s"));
|
|
||||||
|
|
||||||
error (0, 0, format, quotearg_n_style (0, ARGMATCH_QUOTING_STYLE, value),
|
|
||||||
quote_n (1, context));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* List the valid arguments for argmatch.
|
|
||||||
ARGLIST is the same as in argmatch.
|
|
||||||
VALLIST is a pointer to an array of values.
|
|
||||||
VALSIZE is the size of the elements of VALLIST */
|
|
||||||
void
|
|
||||||
argmatch_valid (const char *const *arglist,
|
|
||||||
const char *vallist, size_t valsize)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
const char *last_val = NULL;
|
|
||||||
|
|
||||||
/* We try to put synonyms on the same line. The assumption is that
|
|
||||||
synonyms follow each other */
|
|
||||||
fprintf (stderr, _("Valid arguments are:"));
|
|
||||||
for (i = 0; arglist[i]; i++)
|
|
||||||
if ((i == 0)
|
|
||||||
|| memcmp (last_val, vallist + valsize * i, valsize))
|
|
||||||
{
|
|
||||||
fprintf (stderr, "\n - `%s'", arglist[i]);
|
|
||||||
last_val = vallist + valsize * i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf (stderr, ", `%s'", arglist[i]);
|
|
||||||
}
|
|
||||||
putc ('\n', stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Never failing versions of the previous functions.
|
|
||||||
|
|
||||||
CONTEXT is the context for which argmatch is called (e.g.,
|
|
||||||
"--version-control", or "$VERSION_CONTROL" etc.). Upon failure,
|
|
||||||
calls the (supposed never to return) function EXIT_FN. */
|
|
||||||
|
|
||||||
ptrdiff_t
|
|
||||||
__xargmatch_internal (const char *context,
|
|
||||||
const char *arg, const char *const *arglist,
|
|
||||||
const char *vallist, size_t valsize,
|
|
||||||
argmatch_exit_fn exit_fn)
|
|
||||||
{
|
|
||||||
ptrdiff_t res = argmatch (arg, arglist, vallist, valsize);
|
|
||||||
if (res >= 0)
|
|
||||||
/* Success. */
|
|
||||||
return res;
|
|
||||||
|
|
||||||
/* We failed. Explain why. */
|
|
||||||
argmatch_invalid (context, arg, res);
|
|
||||||
argmatch_valid (arglist, vallist, valsize);
|
|
||||||
(*exit_fn) ();
|
|
||||||
|
|
||||||
return -1; /* To please the compilers. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look for VALUE in VALLIST, an array of objects of size VALSIZE and
|
|
||||||
return the first corresponding argument in ARGLIST */
|
|
||||||
const char *
|
|
||||||
argmatch_to_argument (const char *value,
|
|
||||||
const char *const *arglist,
|
|
||||||
const char *vallist, size_t valsize)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; arglist[i]; i++)
|
|
||||||
if (!memcmp (value, vallist + valsize * i, valsize))
|
|
||||||
return arglist[i];
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TEST
|
|
||||||
/*
|
|
||||||
* Based on "getversion.c" by David MacKenzie <[email protected]>
|
|
||||||
*/
|
|
||||||
char *program_name;
|
|
||||||
|
|
||||||
/* When to make backup files. */
|
|
||||||
enum backup_type
|
|
||||||
{
|
|
||||||
/* Never make backups. */
|
|
||||||
no_backups,
|
|
||||||
|
|
||||||
/* Make simple backups of every file. */
|
|
||||||
simple_backups,
|
|
||||||
|
|
||||||
/* Make numbered backups of files that already have numbered backups,
|
|
||||||
and simple backups of the others. */
|
|
||||||
numbered_existing_backups,
|
|
||||||
|
|
||||||
/* Make numbered backups of every file. */
|
|
||||||
numbered_backups
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Two tables describing arguments (keys) and their corresponding
|
|
||||||
values */
|
|
||||||
static const char *const backup_args[] =
|
|
||||||
{
|
|
||||||
"no", "none", "off",
|
|
||||||
"simple", "never",
|
|
||||||
"existing", "nil",
|
|
||||||
"numbered", "t",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const enum backup_type backup_vals[] =
|
|
||||||
{
|
|
||||||
no_backups, no_backups, no_backups,
|
|
||||||
simple_backups, simple_backups,
|
|
||||||
numbered_existing_backups, numbered_existing_backups,
|
|
||||||
numbered_backups, numbered_backups
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, const char *const *argv)
|
|
||||||
{
|
|
||||||
const char *cp;
|
|
||||||
enum backup_type backup_type = no_backups;
|
|
||||||
|
|
||||||
program_name = (char *) argv[0];
|
|
||||||
|
|
||||||
if (argc > 2)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", program_name);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cp = getenv ("VERSION_CONTROL")))
|
|
||||||
backup_type = XARGMATCH ("$VERSION_CONTROL", cp,
|
|
||||||
backup_args, backup_vals);
|
|
||||||
|
|
||||||
if (argc == 2)
|
|
||||||
backup_type = XARGMATCH (program_name, argv[1],
|
|
||||||
backup_args, backup_vals);
|
|
||||||
|
|
||||||
printf ("The version control is `%s'\n",
|
|
||||||
ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
/* argmatch.h -- definitions and prototypes for argmatch.c
|
|
||||||
|
|
||||||
Copyright (C) 1990, 1998, 1999, 2001, 2002, 2004, 2005 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by David MacKenzie <[email protected]>
|
|
||||||
Modified by Akim Demaille <[email protected]> */
|
|
||||||
|
|
||||||
#ifndef ARGMATCH_H_
|
|
||||||
# define ARGMATCH_H_ 1
|
|
||||||
|
|
||||||
# include <stddef.h>
|
|
||||||
|
|
||||||
# include "verify.h"
|
|
||||||
|
|
||||||
# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
|
|
||||||
|
|
||||||
/* Assert there are as many real arguments as there are values
|
|
||||||
(argument list ends with a NULL guard). */
|
|
||||||
|
|
||||||
# define ARGMATCH_VERIFY(Arglist, Vallist) \
|
|
||||||
verify (ARRAY_CARDINALITY (Arglist) == ARRAY_CARDINALITY (Vallist) + 1)
|
|
||||||
|
|
||||||
/* Return the index of the element of ARGLIST (NULL terminated) that
|
|
||||||
matches with ARG. If VALLIST is not NULL, then use it to resolve
|
|
||||||
false ambiguities (i.e., different matches of ARG but corresponding
|
|
||||||
to the same values in VALLIST). */
|
|
||||||
|
|
||||||
ptrdiff_t argmatch (char const *arg, char const *const *arglist,
|
|
||||||
char const *vallist, size_t valsize);
|
|
||||||
|
|
||||||
# define ARGMATCH(Arg, Arglist, Vallist) \
|
|
||||||
argmatch (Arg, Arglist, (char const *) (Vallist), sizeof *(Vallist))
|
|
||||||
|
|
||||||
/* xargmatch calls this function when it fails. This function should not
|
|
||||||
return. By default, this is a function that calls ARGMATCH_DIE which
|
|
||||||
in turn defaults to `exit (exit_failure)'. */
|
|
||||||
typedef void (*argmatch_exit_fn) (void);
|
|
||||||
extern argmatch_exit_fn argmatch_die;
|
|
||||||
|
|
||||||
/* Report on stderr why argmatch failed. Report correct values. */
|
|
||||||
|
|
||||||
void argmatch_invalid (char const *context, char const *value,
|
|
||||||
ptrdiff_t problem);
|
|
||||||
|
|
||||||
/* Left for compatibility with the old name invalid_arg */
|
|
||||||
|
|
||||||
# define invalid_arg(Context, Value, Problem) \
|
|
||||||
argmatch_invalid (Context, Value, Problem)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Report on stderr the list of possible arguments. */
|
|
||||||
|
|
||||||
void argmatch_valid (char const *const *arglist,
|
|
||||||
char const *vallist, size_t valsize);
|
|
||||||
|
|
||||||
# define ARGMATCH_VALID(Arglist, Vallist) \
|
|
||||||
argmatch_valid (Arglist, (char const *) (Vallist), sizeof *(Vallist))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Same as argmatch, but upon failure, reports a explanation on the
|
|
||||||
failure, and exits using the function EXIT_FN. */
|
|
||||||
|
|
||||||
ptrdiff_t __xargmatch_internal (char const *context,
|
|
||||||
char const *arg, char const *const *arglist,
|
|
||||||
char const *vallist, size_t valsize,
|
|
||||||
argmatch_exit_fn exit_fn);
|
|
||||||
|
|
||||||
/* Programmer friendly interface to __xargmatch_internal. */
|
|
||||||
|
|
||||||
# define XARGMATCH(Context, Arg, Arglist, Vallist) \
|
|
||||||
((Vallist) [__xargmatch_internal (Context, Arg, Arglist, \
|
|
||||||
(char const *) (Vallist), \
|
|
||||||
sizeof *(Vallist), \
|
|
||||||
argmatch_die)])
|
|
||||||
|
|
||||||
/* Convert a value into a corresponding argument. */
|
|
||||||
|
|
||||||
char const *argmatch_to_argument (char const *value,
|
|
||||||
char const *const *arglist,
|
|
||||||
char const *vallist, size_t valsize);
|
|
||||||
|
|
||||||
# define ARGMATCH_TO_ARGUMENT(Value, Arglist, Vallist) \
|
|
||||||
argmatch_to_argument (Value, Arglist, \
|
|
||||||
(char const *) (Vallist), sizeof *(Vallist))
|
|
||||||
|
|
||||||
#endif /* ARGMATCH_H_ */
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
/* Define an at-style functions like fstatat, unlinkat, fchownat, etc.
|
|
||||||
Copyright (C) 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Jim Meyering */
|
|
||||||
|
|
||||||
#define CALL_FUNC(F) \
|
|
||||||
(AT_FUNC_USE_F1_COND \
|
|
||||||
? AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS) \
|
|
||||||
: AT_FUNC_F2 (F AT_FUNC_POST_FILE_ARGS))
|
|
||||||
|
|
||||||
/* Call AT_FUNC_F1 or AT_FUNC_F2 (testing AT_FUNC_USE_F1_COND to
|
|
||||||
determine which) to operate on FILE, which is in the directory
|
|
||||||
open on descriptor FD. If possible, do it without changing the
|
|
||||||
working directory. Otherwise, resort to using save_cwd/fchdir,
|
|
||||||
then AT_FUNC_F?/restore_cwd. If either the save_cwd or the restore_cwd
|
|
||||||
fails, then give a diagnostic and exit nonzero. */
|
|
||||||
int
|
|
||||||
AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS)
|
|
||||||
{
|
|
||||||
struct saved_cwd saved_cwd;
|
|
||||||
int saved_errno;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file))
|
|
||||||
return CALL_FUNC (file);
|
|
||||||
|
|
||||||
{
|
|
||||||
char buf[OPENAT_BUFFER_SIZE];
|
|
||||||
char *proc_file = openat_proc_name (buf, fd, file);
|
|
||||||
if (proc_file)
|
|
||||||
{
|
|
||||||
int proc_result = CALL_FUNC (proc_file);
|
|
||||||
int proc_errno = errno;
|
|
||||||
if (proc_file != buf)
|
|
||||||
free (proc_file);
|
|
||||||
/* If the syscall succeeds, or if it fails with an unexpected
|
|
||||||
errno value, then return right away. Otherwise, fall through
|
|
||||||
and resort to using save_cwd/restore_cwd. */
|
|
||||||
if (0 <= proc_result)
|
|
||||||
return proc_result;
|
|
||||||
if (! EXPECTED_ERRNO (proc_errno))
|
|
||||||
{
|
|
||||||
errno = proc_errno;
|
|
||||||
return proc_result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (save_cwd (&saved_cwd) != 0)
|
|
||||||
openat_save_fail (errno);
|
|
||||||
|
|
||||||
if (fchdir (fd) != 0)
|
|
||||||
{
|
|
||||||
saved_errno = errno;
|
|
||||||
free_cwd (&saved_cwd);
|
|
||||||
errno = saved_errno;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CALL_FUNC (file);
|
|
||||||
saved_errno = (err < 0 ? errno : 0);
|
|
||||||
|
|
||||||
if (restore_cwd (&saved_cwd) != 0)
|
|
||||||
openat_restore_fail (errno);
|
|
||||||
|
|
||||||
free_cwd (&saved_cwd);
|
|
||||||
|
|
||||||
if (saved_errno)
|
|
||||||
errno = saved_errno;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#undef CALL_FUNC
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
/* basename.c -- return the last element in a file name
|
|
||||||
|
|
||||||
Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "dirname.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "xalloc.h"
|
|
||||||
#include "xstrndup.h"
|
|
||||||
|
|
||||||
/* Return the address of the last file name component of NAME. If
|
|
||||||
NAME has no relative file name components because it is a file
|
|
||||||
system root, return the empty string. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
last_component (char const *name)
|
|
||||||
{
|
|
||||||
char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
|
|
||||||
char const *p;
|
|
||||||
bool saw_slash = false;
|
|
||||||
|
|
||||||
while (ISSLASH (*base))
|
|
||||||
base++;
|
|
||||||
|
|
||||||
for (p = base; *p; p++)
|
|
||||||
{
|
|
||||||
if (ISSLASH (*p))
|
|
||||||
saw_slash = true;
|
|
||||||
else if (saw_slash)
|
|
||||||
{
|
|
||||||
base = p;
|
|
||||||
saw_slash = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (char *) base;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* In general, we can't use the builtin `basename' function if available,
|
|
||||||
since it has different meanings in different environments.
|
|
||||||
In some environments the builtin `basename' modifies its argument.
|
|
||||||
|
|
||||||
Return the last file name component of NAME, allocated with
|
|
||||||
xmalloc. On systems with drive letters, a leading "./"
|
|
||||||
distinguishes relative names that would otherwise look like a drive
|
|
||||||
letter. Unlike POSIX basename(), NAME cannot be NULL,
|
|
||||||
base_name("") returns "", and the first trailing slash is not
|
|
||||||
stripped.
|
|
||||||
|
|
||||||
If lstat (NAME) would succeed, then { chdir (dir_name (NAME));
|
|
||||||
lstat (base_name (NAME)); } will access the same file. Likewise,
|
|
||||||
if the sequence { chdir (dir_name (NAME));
|
|
||||||
rename (base_name (NAME), "foo"); } succeeds, you have renamed NAME
|
|
||||||
to "foo" in the same directory NAME was in. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
base_name (char const *name)
|
|
||||||
{
|
|
||||||
char const *base = last_component (name);
|
|
||||||
size_t length;
|
|
||||||
|
|
||||||
/* If there is no last component, then name is a file system root or the
|
|
||||||
empty string. */
|
|
||||||
if (! *base)
|
|
||||||
return xstrndup (name, base_len (name));
|
|
||||||
|
|
||||||
/* Collapse a sequence of trailing slashes into one. */
|
|
||||||
length = base_len (base);
|
|
||||||
if (ISSLASH (base[length]))
|
|
||||||
length++;
|
|
||||||
|
|
||||||
/* On systems with drive letters, `a/b:c' must return `./b:c' rather
|
|
||||||
than `b:c' to avoid confusion with a drive letter. On systems
|
|
||||||
with pure POSIX semantics, this is not an issue. */
|
|
||||||
if (FILE_SYSTEM_PREFIX_LEN (base))
|
|
||||||
{
|
|
||||||
char *p = xmalloc (length + 3);
|
|
||||||
p[0] = '.';
|
|
||||||
p[1] = '/';
|
|
||||||
memcpy (p + 2, base, length);
|
|
||||||
p[length + 2] = '\0';
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally, copy the basename. */
|
|
||||||
return xstrndup (base, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the length of the basename NAME. Typically NAME is the
|
|
||||||
value returned by base_name or last_component. Act like strlen
|
|
||||||
(NAME), except omit all trailing slashes. */
|
|
||||||
|
|
||||||
size_t
|
|
||||||
base_len (char const *name)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
|
|
||||||
|
|
||||||
for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1
|
|
||||||
&& ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len
|
|
||||||
&& len == prefix_len && ISSLASH (name[prefix_len]))
|
|
||||||
return prefix_len + 1;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
/* Binary mode I/O.
|
|
||||||
Copyright (C) 2001, 2003, 2005 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef _BINARY_H
|
|
||||||
#define _BINARY_H
|
|
||||||
|
|
||||||
/* For systems that distinguish between text and binary I/O.
|
|
||||||
O_BINARY is usually declared in <fcntl.h>. */
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
/* The MSVC7 <stdio.h> doesn't like to be included after '#define fileno ...',
|
|
||||||
so we include it here first. */
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#if !defined O_BINARY && defined _O_BINARY
|
|
||||||
/* For MSC-compatible compilers. */
|
|
||||||
# define O_BINARY _O_BINARY
|
|
||||||
# define O_TEXT _O_TEXT
|
|
||||||
#endif
|
|
||||||
#ifdef __BEOS__
|
|
||||||
/* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */
|
|
||||||
# undef O_BINARY
|
|
||||||
# undef O_TEXT
|
|
||||||
#endif
|
|
||||||
#if O_BINARY
|
|
||||||
# if !(defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__)
|
|
||||||
# define setmode _setmode
|
|
||||||
# undef fileno
|
|
||||||
# define fileno _fileno
|
|
||||||
# endif
|
|
||||||
# if defined __DJGPP__ || defined __CYGWIN__
|
|
||||||
# include <io.h> /* declares setmode() */
|
|
||||||
# endif
|
|
||||||
# ifdef __DJGPP__
|
|
||||||
# include <unistd.h> /* declares isatty() */
|
|
||||||
# /* Avoid putting stdin/stdout in binary mode if it is connected to the
|
|
||||||
# console, because that would make it impossible for the user to
|
|
||||||
# interrupt the program through Ctrl-C or Ctrl-Break. */
|
|
||||||
# define SET_BINARY(fd) (!isatty (fd) ? (setmode (fd, O_BINARY), 0) : 0)
|
|
||||||
# else
|
|
||||||
# define SET_BINARY(fd) setmode (fd, O_BINARY)
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
/* On reasonable systems, binary I/O is the default. */
|
|
||||||
# undef O_BINARY
|
|
||||||
# define O_BINARY 0
|
|
||||||
# define SET_BINARY(fd) /* nothing */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _BINARY_H */
|
|
||||||
@@ -1,362 +0,0 @@
|
|||||||
/* Return the canonical absolute name of a given file.
|
|
||||||
Copyright (C) 1996-2003, 2005-2007 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Avoid a clash of our rpl_realpath() function with the prototype in
|
|
||||||
<stdlib.h> on Solaris 2.5.1. */
|
|
||||||
#undef realpath
|
|
||||||
|
|
||||||
#if !HAVE_CANONICALIZE_FILE_NAME || defined _LIBC
|
|
||||||
|
|
||||||
#include <alloca.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include "canonicalize.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#if HAVE_UNISTD_H || defined _LIBC
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#if HAVE_SYS_PARAM_H || defined _LIBC
|
|
||||||
# include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
#ifndef MAXSYMLINKS
|
|
||||||
# define MAXSYMLINKS 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#ifndef _LIBC
|
|
||||||
# define __set_errno(e) errno = (e)
|
|
||||||
# ifndef ENAMETOOLONG
|
|
||||||
# define ENAMETOOLONG EINVAL
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
# include <shlib-compat.h>
|
|
||||||
#else
|
|
||||||
# define SHLIB_COMPAT(lib, introduced, obsoleted) 0
|
|
||||||
# define versioned_symbol(lib, local, symbol, version)
|
|
||||||
# define compat_symbol(lib, local, symbol, version)
|
|
||||||
# define weak_alias(local, symbol)
|
|
||||||
# define __canonicalize_file_name canonicalize_file_name
|
|
||||||
# define __realpath rpl_realpath
|
|
||||||
# include "pathmax.h"
|
|
||||||
# include "malloca.h"
|
|
||||||
# if HAVE_GETCWD
|
|
||||||
# ifdef VMS
|
|
||||||
/* We want the directory in Unix syntax, not in VMS syntax. */
|
|
||||||
# define __getcwd(buf, max) getcwd (buf, max, 0)
|
|
||||||
# else
|
|
||||||
# define __getcwd getcwd
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define __getcwd(buf, max) getwd (buf)
|
|
||||||
# endif
|
|
||||||
# define __readlink readlink
|
|
||||||
/* On systems without symbolic links, call stat() instead of lstat(). */
|
|
||||||
# if !defined S_ISNLK && !HAVE_READLINK
|
|
||||||
# define lstat stat
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Return the canonical absolute name of file NAME. A canonical name
|
|
||||||
does not contain any `.', `..' components nor any repeated path
|
|
||||||
separators ('/') or symlinks. All path components must exist. If
|
|
||||||
RESOLVED is null, the result is malloc'd; otherwise, if the
|
|
||||||
canonical name is PATH_MAX chars or more, returns null with `errno'
|
|
||||||
set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars,
|
|
||||||
returns the name in RESOLVED. If the name cannot be resolved and
|
|
||||||
RESOLVED is non-NULL, it contains the path of the first component
|
|
||||||
that cannot be resolved. If the path can be resolved, RESOLVED
|
|
||||||
holds the same value as the value returned. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
__realpath (const char *name, char *resolved)
|
|
||||||
{
|
|
||||||
char *rpath, *dest, *extra_buf = NULL;
|
|
||||||
const char *start, *end, *rpath_limit;
|
|
||||||
long int path_max;
|
|
||||||
#if HAVE_READLINK
|
|
||||||
int num_links = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (name == NULL)
|
|
||||||
{
|
|
||||||
/* As per Single Unix Specification V2 we must return an error if
|
|
||||||
either parameter is a null pointer. We extend this to allow
|
|
||||||
the RESOLVED parameter to be NULL in case the we are expected to
|
|
||||||
allocate the room for the return value. */
|
|
||||||
__set_errno (EINVAL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name[0] == '\0')
|
|
||||||
{
|
|
||||||
/* As per Single Unix Specification V2 we must return an error if
|
|
||||||
the name argument points to an empty string. */
|
|
||||||
__set_errno (ENOENT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PATH_MAX
|
|
||||||
path_max = PATH_MAX;
|
|
||||||
#else
|
|
||||||
path_max = pathconf (name, _PC_PATH_MAX);
|
|
||||||
if (path_max <= 0)
|
|
||||||
path_max = 1024;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (resolved == NULL)
|
|
||||||
{
|
|
||||||
rpath = malloc (path_max);
|
|
||||||
if (rpath == NULL)
|
|
||||||
{
|
|
||||||
/* It's easier to set errno to ENOMEM than to rely on the
|
|
||||||
'malloc-posix' gnulib module. */
|
|
||||||
errno = ENOMEM;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rpath = resolved;
|
|
||||||
rpath_limit = rpath + path_max;
|
|
||||||
|
|
||||||
if (name[0] != '/')
|
|
||||||
{
|
|
||||||
if (!__getcwd (rpath, path_max))
|
|
||||||
{
|
|
||||||
rpath[0] = '\0';
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
dest = strchr (rpath, '\0');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rpath[0] = '/';
|
|
||||||
dest = rpath + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (start = end = name; *start; start = end)
|
|
||||||
{
|
|
||||||
#ifdef _LIBC
|
|
||||||
struct stat64 st;
|
|
||||||
#else
|
|
||||||
struct stat st;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Skip sequence of multiple path-separators. */
|
|
||||||
while (*start == '/')
|
|
||||||
++start;
|
|
||||||
|
|
||||||
/* Find end of path component. */
|
|
||||||
for (end = start; *end && *end != '/'; ++end)
|
|
||||||
/* Nothing. */;
|
|
||||||
|
|
||||||
if (end - start == 0)
|
|
||||||
break;
|
|
||||||
else if (end - start == 1 && start[0] == '.')
|
|
||||||
/* nothing */;
|
|
||||||
else if (end - start == 2 && start[0] == '.' && start[1] == '.')
|
|
||||||
{
|
|
||||||
/* Back up to previous component, ignore if at root already. */
|
|
||||||
if (dest > rpath + 1)
|
|
||||||
while ((--dest)[-1] != '/');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t new_size;
|
|
||||||
|
|
||||||
if (dest[-1] != '/')
|
|
||||||
*dest++ = '/';
|
|
||||||
|
|
||||||
if (dest + (end - start) >= rpath_limit)
|
|
||||||
{
|
|
||||||
ptrdiff_t dest_offset = dest - rpath;
|
|
||||||
char *new_rpath;
|
|
||||||
|
|
||||||
if (resolved)
|
|
||||||
{
|
|
||||||
__set_errno (ENAMETOOLONG);
|
|
||||||
if (dest > rpath + 1)
|
|
||||||
dest--;
|
|
||||||
*dest = '\0';
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
new_size = rpath_limit - rpath;
|
|
||||||
if (end - start + 1 > path_max)
|
|
||||||
new_size += end - start + 1;
|
|
||||||
else
|
|
||||||
new_size += path_max;
|
|
||||||
new_rpath = (char *) realloc (rpath, new_size);
|
|
||||||
if (new_rpath == NULL)
|
|
||||||
{
|
|
||||||
/* It's easier to set errno to ENOMEM than to rely on the
|
|
||||||
'realloc-posix' gnulib module. */
|
|
||||||
errno = ENOMEM;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
rpath = new_rpath;
|
|
||||||
rpath_limit = rpath + new_size;
|
|
||||||
|
|
||||||
dest = rpath + dest_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
dest = __mempcpy (dest, start, end - start);
|
|
||||||
#else
|
|
||||||
memcpy (dest, start, end - start);
|
|
||||||
dest += end - start;
|
|
||||||
#endif
|
|
||||||
*dest = '\0';
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
|
|
||||||
#else
|
|
||||||
if (lstat (rpath, &st) < 0)
|
|
||||||
#endif
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
#if HAVE_READLINK
|
|
||||||
if (S_ISLNK (st.st_mode))
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
size_t len;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
if (++num_links > MAXSYMLINKS)
|
|
||||||
{
|
|
||||||
__set_errno (ELOOP);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = malloca (path_max);
|
|
||||||
if (!buf)
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = __readlink (rpath, buf, path_max);
|
|
||||||
if (n < 0)
|
|
||||||
{
|
|
||||||
int saved_errno = errno;
|
|
||||||
freea (buf);
|
|
||||||
errno = saved_errno;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
buf[n] = '\0';
|
|
||||||
|
|
||||||
if (!extra_buf)
|
|
||||||
{
|
|
||||||
extra_buf = malloca (path_max);
|
|
||||||
if (!extra_buf)
|
|
||||||
{
|
|
||||||
freea (buf);
|
|
||||||
errno = ENOMEM;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen (end);
|
|
||||||
if ((long int) (n + len) >= path_max)
|
|
||||||
{
|
|
||||||
freea (buf);
|
|
||||||
__set_errno (ENAMETOOLONG);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Careful here, end may be a pointer into extra_buf... */
|
|
||||||
memmove (&extra_buf[n], end, len + 1);
|
|
||||||
name = end = memcpy (extra_buf, buf, n);
|
|
||||||
|
|
||||||
if (buf[0] == '/')
|
|
||||||
dest = rpath + 1; /* It's an absolute symlink */
|
|
||||||
else
|
|
||||||
/* Back up to previous component, ignore if at root already: */
|
|
||||||
if (dest > rpath + 1)
|
|
||||||
while ((--dest)[-1] != '/');
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dest > rpath + 1 && dest[-1] == '/')
|
|
||||||
--dest;
|
|
||||||
*dest = '\0';
|
|
||||||
|
|
||||||
if (extra_buf)
|
|
||||||
freea (extra_buf);
|
|
||||||
|
|
||||||
return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath;
|
|
||||||
|
|
||||||
error:
|
|
||||||
{
|
|
||||||
int saved_errno = errno;
|
|
||||||
if (extra_buf)
|
|
||||||
freea (extra_buf);
|
|
||||||
if (resolved)
|
|
||||||
strcpy (resolved, rpath);
|
|
||||||
else
|
|
||||||
free (rpath);
|
|
||||||
errno = saved_errno;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#ifdef _LIBC
|
|
||||||
versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
|
|
||||||
char *
|
|
||||||
__old_realpath (const char *name, char *resolved)
|
|
||||||
{
|
|
||||||
if (resolved == NULL)
|
|
||||||
{
|
|
||||||
__set_errno (EINVAL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return __realpath (name, resolved);
|
|
||||||
}
|
|
||||||
compat_symbol (libc, __old_realpath, realpath, GLIBC_2_0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
char *
|
|
||||||
__canonicalize_file_name (const char *name)
|
|
||||||
{
|
|
||||||
return __realpath (name, NULL);
|
|
||||||
}
|
|
||||||
weak_alias (__canonicalize_file_name, canonicalize_file_name)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* This declaration is solely to ensure that after preprocessing
|
|
||||||
this file is never empty. */
|
|
||||||
typedef int dummy;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
/* Return the canonical absolute name of a given file.
|
|
||||||
Copyright (C) 1996-2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "canonicalize.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#if HAVE_SYS_PARAM_H
|
|
||||||
# include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "file-set.h"
|
|
||||||
#include "filenamecat.h"
|
|
||||||
#include "hash-triple.h"
|
|
||||||
#include "xalloc.h"
|
|
||||||
#include "xgetcwd.h"
|
|
||||||
|
|
||||||
#ifndef ELOOP
|
|
||||||
# define ELOOP 0
|
|
||||||
#endif
|
|
||||||
#ifndef __set_errno
|
|
||||||
# define __set_errno(Val) errno = (Val)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pathmax.h"
|
|
||||||
#include "areadlink.h"
|
|
||||||
|
|
||||||
#if !HAVE_CANONICALIZE_FILE_NAME
|
|
||||||
/* Return the canonical absolute name of file NAME. A canonical name
|
|
||||||
does not contain any `.', `..' components nor any repeated file name
|
|
||||||
separators ('/') or symlinks. All components must exist.
|
|
||||||
The result is malloc'd. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
canonicalize_file_name (const char *name)
|
|
||||||
{
|
|
||||||
# if HAVE_RESOLVEPATH
|
|
||||||
|
|
||||||
char *resolved, *extra_buf = NULL;
|
|
||||||
size_t resolved_size;
|
|
||||||
ssize_t resolved_len;
|
|
||||||
|
|
||||||
if (name == NULL)
|
|
||||||
{
|
|
||||||
__set_errno (EINVAL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name[0] == '\0')
|
|
||||||
{
|
|
||||||
__set_errno (ENOENT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All known hosts with resolvepath (e.g. Solaris 7) don't turn
|
|
||||||
relative names into absolute ones, so prepend the working
|
|
||||||
directory if the file name is not absolute. */
|
|
||||||
if (name[0] != '/')
|
|
||||||
{
|
|
||||||
char *wd;
|
|
||||||
|
|
||||||
if (!(wd = xgetcwd ()))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
extra_buf = file_name_concat (wd, name, NULL);
|
|
||||||
name = extra_buf;
|
|
||||||
free (wd);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolved_size = strlen (name);
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
resolved_size = 2 * resolved_size + 1;
|
|
||||||
resolved = xmalloc (resolved_size);
|
|
||||||
resolved_len = resolvepath (name, resolved, resolved_size);
|
|
||||||
if (resolved_len < 0)
|
|
||||||
{
|
|
||||||
free (resolved);
|
|
||||||
free (extra_buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (resolved_len < resolved_size)
|
|
||||||
break;
|
|
||||||
free (resolved);
|
|
||||||
}
|
|
||||||
|
|
||||||
free (extra_buf);
|
|
||||||
|
|
||||||
/* NUL-terminate the resulting name. */
|
|
||||||
resolved[resolved_len] = '\0';
|
|
||||||
|
|
||||||
return resolved;
|
|
||||||
|
|
||||||
# else
|
|
||||||
|
|
||||||
return canonicalize_filename_mode (name, CAN_EXISTING);
|
|
||||||
|
|
||||||
# endif /* !HAVE_RESOLVEPATH */
|
|
||||||
}
|
|
||||||
#endif /* !HAVE_CANONICALIZE_FILE_NAME */
|
|
||||||
|
|
||||||
/* Return true if we've already seen the triple, <FILENAME, dev, ino>.
|
|
||||||
If *HT is not initialized, initialize it. */
|
|
||||||
static bool
|
|
||||||
seen_triple (Hash_table **ht, char const *filename, struct stat const *st)
|
|
||||||
{
|
|
||||||
if (*ht == NULL)
|
|
||||||
{
|
|
||||||
size_t initial_capacity = 7;
|
|
||||||
*ht = hash_initialize (initial_capacity,
|
|
||||||
NULL,
|
|
||||||
triple_hash,
|
|
||||||
triple_compare_ino_str,
|
|
||||||
triple_free);
|
|
||||||
if (*ht == NULL)
|
|
||||||
xalloc_die ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seen_file (*ht, filename, st))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
record_file (*ht, filename, st);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the canonical absolute name of file NAME. A canonical name
|
|
||||||
does not contain any `.', `..' components nor any repeated file name
|
|
||||||
separators ('/') or symlinks. Whether components must exist
|
|
||||||
or not depends on canonicalize mode. The result is malloc'd. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
canonicalize_filename_mode (const char *name, canonicalize_mode_t can_mode)
|
|
||||||
{
|
|
||||||
char *rname, *dest, *extra_buf = NULL;
|
|
||||||
char const *start;
|
|
||||||
char const *end;
|
|
||||||
char const *rname_limit;
|
|
||||||
size_t extra_len = 0;
|
|
||||||
Hash_table *ht = NULL;
|
|
||||||
|
|
||||||
if (name == NULL)
|
|
||||||
{
|
|
||||||
__set_errno (EINVAL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name[0] == '\0')
|
|
||||||
{
|
|
||||||
__set_errno (ENOENT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name[0] != '/')
|
|
||||||
{
|
|
||||||
rname = xgetcwd ();
|
|
||||||
if (!rname)
|
|
||||||
return NULL;
|
|
||||||
dest = strchr (rname, '\0');
|
|
||||||
if (dest - rname < PATH_MAX)
|
|
||||||
{
|
|
||||||
char *p = xrealloc (rname, PATH_MAX);
|
|
||||||
dest = p + (dest - rname);
|
|
||||||
rname = p;
|
|
||||||
rname_limit = rname + PATH_MAX;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rname_limit = dest;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rname = xmalloc (PATH_MAX);
|
|
||||||
rname_limit = rname + PATH_MAX;
|
|
||||||
rname[0] = '/';
|
|
||||||
dest = rname + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (start = end = name; *start; start = end)
|
|
||||||
{
|
|
||||||
/* Skip sequence of multiple file name separators. */
|
|
||||||
while (*start == '/')
|
|
||||||
++start;
|
|
||||||
|
|
||||||
/* Find end of component. */
|
|
||||||
for (end = start; *end && *end != '/'; ++end)
|
|
||||||
/* Nothing. */;
|
|
||||||
|
|
||||||
if (end - start == 0)
|
|
||||||
break;
|
|
||||||
else if (end - start == 1 && start[0] == '.')
|
|
||||||
/* nothing */;
|
|
||||||
else if (end - start == 2 && start[0] == '.' && start[1] == '.')
|
|
||||||
{
|
|
||||||
/* Back up to previous component, ignore if at root already. */
|
|
||||||
if (dest > rname + 1)
|
|
||||||
while ((--dest)[-1] != '/');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (dest[-1] != '/')
|
|
||||||
*dest++ = '/';
|
|
||||||
|
|
||||||
if (dest + (end - start) >= rname_limit)
|
|
||||||
{
|
|
||||||
ptrdiff_t dest_offset = dest - rname;
|
|
||||||
size_t new_size = rname_limit - rname;
|
|
||||||
|
|
||||||
if (end - start + 1 > PATH_MAX)
|
|
||||||
new_size += end - start + 1;
|
|
||||||
else
|
|
||||||
new_size += PATH_MAX;
|
|
||||||
rname = xrealloc (rname, new_size);
|
|
||||||
rname_limit = rname + new_size;
|
|
||||||
|
|
||||||
dest = rname + dest_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest = memcpy (dest, start, end - start);
|
|
||||||
dest += end - start;
|
|
||||||
*dest = '\0';
|
|
||||||
|
|
||||||
if (lstat (rname, &st) != 0)
|
|
||||||
{
|
|
||||||
if (can_mode == CAN_EXISTING)
|
|
||||||
goto error;
|
|
||||||
if (can_mode == CAN_ALL_BUT_LAST && *end)
|
|
||||||
goto error;
|
|
||||||
st.st_mode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISLNK (st.st_mode))
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
size_t n, len;
|
|
||||||
|
|
||||||
/* Detect loops. We cannot use the cycle-check module here,
|
|
||||||
since it's actually possible to encounter the same symlink
|
|
||||||
more than once in a given traversal. However, encountering
|
|
||||||
the same symlink,NAME pair twice does indicate a loop. */
|
|
||||||
if (seen_triple (&ht, name, &st))
|
|
||||||
{
|
|
||||||
__set_errno (ELOOP);
|
|
||||||
if (can_mode == CAN_MISSING)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = areadlink_with_size (rname, st.st_size);
|
|
||||||
if (!buf)
|
|
||||||
{
|
|
||||||
if (can_mode == CAN_MISSING && errno != ENOMEM)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = strlen (buf);
|
|
||||||
len = strlen (end);
|
|
||||||
|
|
||||||
if (!extra_len)
|
|
||||||
{
|
|
||||||
extra_len =
|
|
||||||
((n + len + 1) > PATH_MAX) ? (n + len + 1) : PATH_MAX;
|
|
||||||
extra_buf = xmalloc (extra_len);
|
|
||||||
}
|
|
||||||
else if ((n + len + 1) > extra_len)
|
|
||||||
{
|
|
||||||
extra_len = n + len + 1;
|
|
||||||
extra_buf = xrealloc (extra_buf, extra_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Careful here, end may be a pointer into extra_buf... */
|
|
||||||
memmove (&extra_buf[n], end, len + 1);
|
|
||||||
name = end = memcpy (extra_buf, buf, n);
|
|
||||||
|
|
||||||
if (buf[0] == '/')
|
|
||||||
dest = rname + 1; /* It's an absolute symlink */
|
|
||||||
else
|
|
||||||
/* Back up to previous component, ignore if at root already: */
|
|
||||||
if (dest > rname + 1)
|
|
||||||
while ((--dest)[-1] != '/');
|
|
||||||
|
|
||||||
free (buf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!S_ISDIR (st.st_mode) && *end && (can_mode != CAN_MISSING))
|
|
||||||
{
|
|
||||||
errno = ENOTDIR;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dest > rname + 1 && dest[-1] == '/')
|
|
||||||
--dest;
|
|
||||||
*dest = '\0';
|
|
||||||
|
|
||||||
free (extra_buf);
|
|
||||||
if (ht)
|
|
||||||
hash_free (ht);
|
|
||||||
return rname;
|
|
||||||
|
|
||||||
error:
|
|
||||||
free (extra_buf);
|
|
||||||
free (rname);
|
|
||||||
if (ht)
|
|
||||||
hash_free (ht);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/* Return the canonical absolute name of a given file.
|
|
||||||
Copyright (C) 1996-2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef CANONICALIZE_H_
|
|
||||||
# define CANONICALIZE_H_
|
|
||||||
|
|
||||||
# if GNULIB_CANONICALIZE
|
|
||||||
enum canonicalize_mode_t
|
|
||||||
{
|
|
||||||
/* All components must exist. */
|
|
||||||
CAN_EXISTING = 0,
|
|
||||||
|
|
||||||
/* All components excluding last one must exist. */
|
|
||||||
CAN_ALL_BUT_LAST = 1,
|
|
||||||
|
|
||||||
/* No requirements on components existence. */
|
|
||||||
CAN_MISSING = 2
|
|
||||||
};
|
|
||||||
typedef enum canonicalize_mode_t canonicalize_mode_t;
|
|
||||||
|
|
||||||
/* Return a malloc'd string containing the canonical absolute name of
|
|
||||||
the named file. This acts like canonicalize_file_name, except that
|
|
||||||
whether components must exist depends on the canonicalize_mode_t
|
|
||||||
argument. */
|
|
||||||
char *canonicalize_filename_mode (const char *, canonicalize_mode_t);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if HAVE_DECL_CANONICALIZE_FILE_NAME
|
|
||||||
# include <stdlib.h>
|
|
||||||
# else
|
|
||||||
/* Return a malloc'd string containing the canonical absolute name of
|
|
||||||
the named file. If any file name component does not exist or is a
|
|
||||||
symlink to a nonexistent file, return NULL. A canonical name does
|
|
||||||
not contain any `.', `..' components nor any repeated file name
|
|
||||||
separators ('/') or symlinks. */
|
|
||||||
char *canonicalize_file_name (const char *);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif /* !CANONICALIZE_H_ */
|
|
||||||
@@ -1,264 +0,0 @@
|
|||||||
/* provide a chdir function that tries not to fail due to ENAMETOOLONG
|
|
||||||
Copyright (C) 2004, 2005, 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Jim Meyering */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "chdir-long.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "openat.h"
|
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
# error "compile this file only if your system defines PATH_MAX"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct cd_buf
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
cdb_init (struct cd_buf *cdb)
|
|
||||||
{
|
|
||||||
cdb->fd = AT_FDCWD;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
cdb_fchdir (struct cd_buf const *cdb)
|
|
||||||
{
|
|
||||||
return fchdir (cdb->fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
cdb_free (struct cd_buf const *cdb)
|
|
||||||
{
|
|
||||||
if (0 <= cdb->fd)
|
|
||||||
{
|
|
||||||
bool close_fail = close (cdb->fd);
|
|
||||||
assert (! close_fail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a file descriptor of an open directory (or AT_FDCWD), CDB->fd,
|
|
||||||
try to open the CDB->fd-relative directory, DIR. If the open succeeds,
|
|
||||||
update CDB->fd with the resulting descriptor, close the incoming file
|
|
||||||
descriptor, and return zero. Upon failure, return -1 and set errno. */
|
|
||||||
static int
|
|
||||||
cdb_advance_fd (struct cd_buf *cdb, char const *dir)
|
|
||||||
{
|
|
||||||
int new_fd = openat (cdb->fd, dir,
|
|
||||||
O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK);
|
|
||||||
if (new_fd < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
cdb_free (cdb);
|
|
||||||
cdb->fd = new_fd;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a pointer to the first non-slash in S. */
|
|
||||||
static inline char *
|
|
||||||
find_non_slash (char const *s)
|
|
||||||
{
|
|
||||||
size_t n_slash = strspn (s, "/");
|
|
||||||
return (char *) s + n_slash;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is a function much like chdir, but without the PATH_MAX limitation
|
|
||||||
on the length of the directory name. A significant difference is that
|
|
||||||
it must be able to modify (albeit only temporarily) the directory
|
|
||||||
name. It handles an arbitrarily long directory name by operating
|
|
||||||
on manageable portions of the name. On systems without the openat
|
|
||||||
syscall, this means changing the working directory to more and more
|
|
||||||
`distant' points along the long directory name and then restoring
|
|
||||||
the working directory. If any of those attempts to save or restore
|
|
||||||
the working directory fails, this function exits nonzero.
|
|
||||||
|
|
||||||
Note that this function may still fail with errno == ENAMETOOLONG, but
|
|
||||||
only if the specified directory name contains a component that is long
|
|
||||||
enough to provoke such a failure all by itself (e.g. if the component
|
|
||||||
has length PATH_MAX or greater on systems that define PATH_MAX). */
|
|
||||||
|
|
||||||
int
|
|
||||||
chdir_long (char *dir)
|
|
||||||
{
|
|
||||||
int e = chdir (dir);
|
|
||||||
if (e == 0 || errno != ENAMETOOLONG)
|
|
||||||
return e;
|
|
||||||
|
|
||||||
{
|
|
||||||
size_t len = strlen (dir);
|
|
||||||
char *dir_end = dir + len;
|
|
||||||
struct cd_buf cdb;
|
|
||||||
size_t n_leading_slash;
|
|
||||||
|
|
||||||
cdb_init (&cdb);
|
|
||||||
|
|
||||||
/* If DIR is the empty string, then the chdir above
|
|
||||||
must have failed and set errno to ENOENT. */
|
|
||||||
assert (0 < len);
|
|
||||||
assert (PATH_MAX <= len);
|
|
||||||
|
|
||||||
/* Count leading slashes. */
|
|
||||||
n_leading_slash = strspn (dir, "/");
|
|
||||||
|
|
||||||
/* Handle any leading slashes as well as any name that matches
|
|
||||||
the regular expression, m!^//hostname[/]*! . Handling this
|
|
||||||
prefix separately usually results in a single additional
|
|
||||||
cdb_advance_fd call, but it's worthwhile, since it makes the
|
|
||||||
code in the following loop cleaner. */
|
|
||||||
if (n_leading_slash == 2)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
/* Find next slash.
|
|
||||||
We already know that dir[2] is neither a slash nor '\0'. */
|
|
||||||
char *slash = memchr (dir + 3, '/', dir_end - (dir + 3));
|
|
||||||
if (slash == NULL)
|
|
||||||
{
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*slash = '\0';
|
|
||||||
err = cdb_advance_fd (&cdb, dir);
|
|
||||||
*slash = '/';
|
|
||||||
if (err != 0)
|
|
||||||
goto Fail;
|
|
||||||
dir = find_non_slash (slash + 1);
|
|
||||||
}
|
|
||||||
else if (n_leading_slash)
|
|
||||||
{
|
|
||||||
if (cdb_advance_fd (&cdb, "/") != 0)
|
|
||||||
goto Fail;
|
|
||||||
dir += n_leading_slash;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert (*dir != '/');
|
|
||||||
assert (dir <= dir_end);
|
|
||||||
|
|
||||||
while (PATH_MAX <= dir_end - dir)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
/* Find a slash that is PATH_MAX or fewer bytes away from dir.
|
|
||||||
I.e. see if there is a slash that will give us a name of
|
|
||||||
length PATH_MAX-1 or less. */
|
|
||||||
char *slash = memrchr (dir, '/', PATH_MAX);
|
|
||||||
if (slash == NULL)
|
|
||||||
{
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*slash = '\0';
|
|
||||||
assert (slash - dir < PATH_MAX);
|
|
||||||
err = cdb_advance_fd (&cdb, dir);
|
|
||||||
*slash = '/';
|
|
||||||
if (err != 0)
|
|
||||||
goto Fail;
|
|
||||||
|
|
||||||
dir = find_non_slash (slash + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir < dir_end)
|
|
||||||
{
|
|
||||||
if (cdb_advance_fd (&cdb, dir) != 0)
|
|
||||||
goto Fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cdb_fchdir (&cdb) != 0)
|
|
||||||
goto Fail;
|
|
||||||
|
|
||||||
cdb_free (&cdb);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Fail:
|
|
||||||
{
|
|
||||||
int saved_errno = errno;
|
|
||||||
cdb_free (&cdb);
|
|
||||||
errno = saved_errno;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if TEST_CHDIR
|
|
||||||
|
|
||||||
# include <stdio.h>
|
|
||||||
# include "closeout.h"
|
|
||||||
# include "error.h"
|
|
||||||
|
|
||||||
char *program_name;
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char *line = NULL;
|
|
||||||
size_t n = 0;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
program_name = argv[0];
|
|
||||||
atexit (close_stdout);
|
|
||||||
|
|
||||||
len = getline (&line, &n, stdin);
|
|
||||||
if (len < 0)
|
|
||||||
{
|
|
||||||
int saved_errno = errno;
|
|
||||||
if (feof (stdin))
|
|
||||||
exit (0);
|
|
||||||
|
|
||||||
error (EXIT_FAILURE, saved_errno,
|
|
||||||
"reading standard input");
|
|
||||||
}
|
|
||||||
else if (len == 0)
|
|
||||||
exit (0);
|
|
||||||
|
|
||||||
if (line[len-1] == '\n')
|
|
||||||
line[len-1] = '\0';
|
|
||||||
|
|
||||||
if (chdir_long (line) != 0)
|
|
||||||
error (EXIT_FAILURE, errno,
|
|
||||||
"chdir_long failed: %s", line);
|
|
||||||
|
|
||||||
if (argc <= 1)
|
|
||||||
{
|
|
||||||
/* Using `pwd' here makes sense only if it is a robust implementation,
|
|
||||||
like the one in coreutils after the 2004-04-19 changes. */
|
|
||||||
char const *cmd = "pwd";
|
|
||||||
execlp (cmd, (char *) NULL);
|
|
||||||
error (EXIT_FAILURE, errno, "%s", cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose (stdin);
|
|
||||||
fclose (stderr);
|
|
||||||
|
|
||||||
exit (EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
Local Variables:
|
|
||||||
compile-command: "gcc -DTEST_CHDIR=1 -g -O -W -Wall chdir-long.c libcoreutils.a"
|
|
||||||
End:
|
|
||||||
*/
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/* provide a chdir function that tries not to fail due to ENAMETOOLONG
|
|
||||||
Copyright (C) 2004, 2005 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
# ifdef MAXPATHLEN
|
|
||||||
# define PATH_MAX MAXPATHLEN
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* On systems without PATH_MAX, presume that chdir accepts
|
|
||||||
arbitrarily long directory names. */
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
# define chdir_long(Dir) chdir (Dir)
|
|
||||||
#else
|
|
||||||
int chdir_long (char *dir);
|
|
||||||
#endif
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/* provide consistent interface to chown for systems that don't interpret
|
|
||||||
an ID of -1 as meaning `don't change the corresponding ID'.
|
|
||||||
|
|
||||||
Copyright (C) 1997, 2004, 2005, 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Jim Meyering */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/* Below we refer to the system's chown(). */
|
|
||||||
#undef chown
|
|
||||||
|
|
||||||
/* The results of open() in this file are not used with fchdir,
|
|
||||||
therefore save some unnecessary work in fchdir.c. */
|
|
||||||
#undef open
|
|
||||||
#undef close
|
|
||||||
|
|
||||||
/* Provide a more-closely POSIX-conforming version of chown on
|
|
||||||
systems with one or both of the following problems:
|
|
||||||
- chown doesn't treat an ID of -1 as meaning
|
|
||||||
`don't change the corresponding ID'.
|
|
||||||
- chown doesn't dereference symlinks. */
|
|
||||||
|
|
||||||
int
|
|
||||||
rpl_chown (const char *file, uid_t uid, gid_t gid)
|
|
||||||
{
|
|
||||||
#if CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE
|
|
||||||
if (gid == (gid_t) -1 || uid == (uid_t) -1)
|
|
||||||
{
|
|
||||||
struct stat file_stats;
|
|
||||||
|
|
||||||
/* Stat file to get id(s) that should remain unchanged. */
|
|
||||||
if (stat (file, &file_stats))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (gid == (gid_t) -1)
|
|
||||||
gid = file_stats.st_gid;
|
|
||||||
|
|
||||||
if (uid == (uid_t) -1)
|
|
||||||
uid = file_stats.st_uid;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CHOWN_MODIFIES_SYMLINK
|
|
||||||
{
|
|
||||||
/* Handle the case in which the system-supplied chown function
|
|
||||||
does *not* follow symlinks. Instead, it changes permissions
|
|
||||||
on the symlink itself. To work around that, we open the
|
|
||||||
file (but this can fail due to lack of read or write permission) and
|
|
||||||
use fchown on the resulting descriptor. */
|
|
||||||
int open_flags = O_NONBLOCK | O_NOCTTY;
|
|
||||||
int fd = open (file, O_RDONLY | open_flags);
|
|
||||||
if (0 <= fd
|
|
||||||
|| (errno == EACCES
|
|
||||||
&& 0 <= (fd = open (file, O_WRONLY | open_flags))))
|
|
||||||
{
|
|
||||||
int result = fchown (fd, uid, gid);
|
|
||||||
int saved_errno = errno;
|
|
||||||
|
|
||||||
/* POSIX says fchown can fail with errno == EINVAL on sockets,
|
|
||||||
so fall back on chown in that case. */
|
|
||||||
struct stat sb;
|
|
||||||
bool fchown_socket_failure =
|
|
||||||
(result != 0 && saved_errno == EINVAL
|
|
||||||
&& fstat (fd, &sb) == 0 && S_ISFIFO (sb.st_mode));
|
|
||||||
|
|
||||||
close (fd);
|
|
||||||
|
|
||||||
if (! fchown_socket_failure)
|
|
||||||
{
|
|
||||||
errno = saved_errno;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (errno != EACCES)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return chown (file, uid, gid);
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/* Close a stream, with nicer error checking than fclose's.
|
|
||||||
|
|
||||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "close-stream.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "fpending.h"
|
|
||||||
|
|
||||||
#if USE_UNLOCKED_IO
|
|
||||||
# include "unlocked-io.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Close STREAM. Return 0 if successful, EOF (setting errno)
|
|
||||||
otherwise. A failure might set errno to 0 if the error number
|
|
||||||
cannot be determined.
|
|
||||||
|
|
||||||
If a program writes *anything* to STREAM, that program should close
|
|
||||||
STREAM and make sure that it succeeds before exiting. Otherwise,
|
|
||||||
suppose that you go to the extreme of checking the return status
|
|
||||||
of every function that does an explicit write to STREAM. The last
|
|
||||||
printf can succeed in writing to the internal stream buffer, and yet
|
|
||||||
the fclose(STREAM) could still fail (due e.g., to a disk full error)
|
|
||||||
when it tries to write out that buffered data. Thus, you would be
|
|
||||||
left with an incomplete output file and the offending program would
|
|
||||||
exit successfully. Even calling fflush is not always sufficient,
|
|
||||||
since some file systems (NFS and CODA) buffer written/flushed data
|
|
||||||
until an actual close call.
|
|
||||||
|
|
||||||
Besides, it's wasteful to check the return value from every call
|
|
||||||
that writes to STREAM -- just let the internal stream state record
|
|
||||||
the failure. That's what the ferror test is checking below. */
|
|
||||||
|
|
||||||
int
|
|
||||||
close_stream (FILE *stream)
|
|
||||||
{
|
|
||||||
bool some_pending = (__fpending (stream) != 0);
|
|
||||||
bool prev_fail = (ferror (stream) != 0);
|
|
||||||
bool fclose_fail = (fclose (stream) != 0);
|
|
||||||
|
|
||||||
/* Return an error indication if there was a previous failure or if
|
|
||||||
fclose failed, with one exception: ignore an fclose failure if
|
|
||||||
there was no previous error, no data remains to be flushed, and
|
|
||||||
fclose failed with EBADF. That can happen when a program like cp
|
|
||||||
is invoked like this `cp a b >&-' (i.e., with standard output
|
|
||||||
closed) and doesn't generate any output (hence no previous error
|
|
||||||
and nothing to be flushed). */
|
|
||||||
|
|
||||||
if (prev_fail || (fclose_fail && (some_pending || errno != EBADF)))
|
|
||||||
{
|
|
||||||
if (! fclose_fail)
|
|
||||||
errno = 0;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
int close_stream (FILE *stream);
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
/* Close standard input, rewinding seekable stdin if necessary.
|
|
||||||
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "closein.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "gettext.h"
|
|
||||||
#define _(msgid) gettext (msgid)
|
|
||||||
|
|
||||||
#include "close-stream.h"
|
|
||||||
#include "closeout.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "exitfail.h"
|
|
||||||
#include "freadahead.h"
|
|
||||||
#include "quotearg.h"
|
|
||||||
|
|
||||||
static const char *file_name;
|
|
||||||
|
|
||||||
/* Set the file name to be reported in the event an error is detected
|
|
||||||
on stdin by close_stdin. See also close_stdout_set_file_name, if
|
|
||||||
an error is detected when closing stdout. */
|
|
||||||
void
|
|
||||||
close_stdin_set_file_name (const char *file)
|
|
||||||
{
|
|
||||||
file_name = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close standard input, rewinding any unused input if stdin is
|
|
||||||
seekable. On error, issue a diagnostic and _exit with status
|
|
||||||
'exit_failure'. Then call close_stdout.
|
|
||||||
|
|
||||||
Most programs can get by with close_stdout. close_stdin is only
|
|
||||||
needed when a program wants to guarantee that partially read input
|
|
||||||
from seekable stdin is not consumed, for any subsequent clients.
|
|
||||||
For example, POSIX requires that these two commands behave alike:
|
|
||||||
|
|
||||||
(sed -ne 1q; cat) < file
|
|
||||||
tail -n 1 file
|
|
||||||
|
|
||||||
Since close_stdin is commonly registered via 'atexit', POSIX
|
|
||||||
and the C standard both say that it should not call 'exit',
|
|
||||||
because the behavior is undefined if 'exit' is called more than
|
|
||||||
once. So it calls '_exit' instead of 'exit'. If close_stdin
|
|
||||||
is registered via atexit before other functions are registered,
|
|
||||||
the other functions can act before this _exit is invoked.
|
|
||||||
|
|
||||||
Applications that use close_stdout should flush any streams other
|
|
||||||
than stdin, stdout, and stderr before exiting, since the call to
|
|
||||||
_exit will bypass other buffer flushing. Applications should be
|
|
||||||
flushing and closing other streams anyway, to check for I/O errors.
|
|
||||||
Also, applications should not use tmpfile, since _exit can bypass
|
|
||||||
the removal of these files.
|
|
||||||
|
|
||||||
It's important to detect such failures and exit nonzero because many
|
|
||||||
tools (most notably `make' and other build-management systems) depend
|
|
||||||
on being able to detect failure in other tools via their exit status. */
|
|
||||||
|
|
||||||
void
|
|
||||||
close_stdin (void)
|
|
||||||
{
|
|
||||||
bool fail = false;
|
|
||||||
|
|
||||||
/* There is no need to flush stdin if we can determine quickly that stdin's
|
|
||||||
input buffer is empty; in this case we know that if stdin is seekable,
|
|
||||||
fseeko (stdin, 0, SEEK_CUR) == lseek (0, 0, SEEK_CUR). */
|
|
||||||
if (freadahead (stdin) > 0)
|
|
||||||
{
|
|
||||||
/* Only attempt flush if stdin is seekable, as fflush is entitled to
|
|
||||||
fail on non-seekable streams. */
|
|
||||||
if (fseeko (stdin, 0, SEEK_CUR) == 0 && fflush (stdin) != 0)
|
|
||||||
fail = true;
|
|
||||||
}
|
|
||||||
if (close_stream (stdin) != 0)
|
|
||||||
fail = true;
|
|
||||||
if (fail)
|
|
||||||
{
|
|
||||||
/* Report failure, but defer exit until after closing stdout,
|
|
||||||
since the failure report should still be flushed. */
|
|
||||||
char const *close_error = _("error closing file");
|
|
||||||
if (file_name)
|
|
||||||
error (0, errno, "%s: %s", quotearg_colon (file_name),
|
|
||||||
close_error);
|
|
||||||
else
|
|
||||||
error (0, errno, "%s", close_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
close_stdout ();
|
|
||||||
|
|
||||||
if (fail)
|
|
||||||
_exit (exit_failure);
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/* Close standard input, rewinding seekable stdin if necessary.
|
|
||||||
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef _GL_CLOSEIN_H
|
|
||||||
# define _GL_CLOSEIN_H 1
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
# endif
|
|
||||||
|
|
||||||
void close_stdin_set_file_name (const char *file);
|
|
||||||
void close_stdin (void);
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
/* Close standard output and standard error, exiting with a diagnostic on error.
|
|
||||||
|
|
||||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "closeout.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "gettext.h"
|
|
||||||
#define _(msgid) gettext (msgid)
|
|
||||||
|
|
||||||
#include "close-stream.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "exitfail.h"
|
|
||||||
#include "quotearg.h"
|
|
||||||
|
|
||||||
static const char *file_name;
|
|
||||||
|
|
||||||
/* Set the file name to be reported in the event an error is detected
|
|
||||||
by close_stdout. */
|
|
||||||
void
|
|
||||||
close_stdout_set_file_name (const char *file)
|
|
||||||
{
|
|
||||||
file_name = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close standard output. On error, issue a diagnostic and _exit
|
|
||||||
with status 'exit_failure'.
|
|
||||||
|
|
||||||
Also close standard error. On error, _exit with status 'exit_failure'.
|
|
||||||
|
|
||||||
Since close_stdout is commonly registered via 'atexit', POSIX
|
|
||||||
and the C standard both say that it should not call 'exit',
|
|
||||||
because the behavior is undefined if 'exit' is called more than
|
|
||||||
once. So it calls '_exit' instead of 'exit'. If close_stdout
|
|
||||||
is registered via atexit before other functions are registered,
|
|
||||||
the other functions can act before this _exit is invoked.
|
|
||||||
|
|
||||||
Applications that use close_stdout should flush any streams
|
|
||||||
other than stdout and stderr before exiting, since the call to
|
|
||||||
_exit will bypass other buffer flushing. Applications should
|
|
||||||
be flushing and closing other streams anyway, to check for I/O
|
|
||||||
errors. Also, applications should not use tmpfile, since _exit
|
|
||||||
can bypass the removal of these files.
|
|
||||||
|
|
||||||
It's important to detect such failures and exit nonzero because many
|
|
||||||
tools (most notably `make' and other build-management systems) depend
|
|
||||||
on being able to detect failure in other tools via their exit status. */
|
|
||||||
|
|
||||||
void
|
|
||||||
close_stdout (void)
|
|
||||||
{
|
|
||||||
if (close_stream (stdout) != 0)
|
|
||||||
{
|
|
||||||
char const *write_error = _("write error");
|
|
||||||
if (file_name)
|
|
||||||
error (0, errno, "%s: %s", quotearg_colon (file_name),
|
|
||||||
write_error);
|
|
||||||
else
|
|
||||||
error (0, errno, "%s", write_error);
|
|
||||||
|
|
||||||
_exit (exit_failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (close_stream (stderr) != 0)
|
|
||||||
_exit (exit_failure);
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/* Close standard output and standard error.
|
|
||||||
|
|
||||||
Copyright (C) 1998, 2000, 2003, 2004, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef CLOSEOUT_H
|
|
||||||
# define CLOSEOUT_H 1
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
# endif
|
|
||||||
|
|
||||||
void close_stdout_set_file_name (const char *file);
|
|
||||||
void close_stdout (void);
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
|
||||||
#define PREFIX "/usr/local"
|
|
||||||
#define EXEC_PREFIX "/usr/local"
|
|
||||||
#define BINDIR "/usr/local/bin"
|
|
||||||
#define SBINDIR "/usr/local/sbin"
|
|
||||||
#define LIBEXECDIR "/usr/local/libexec"
|
|
||||||
#define DATAROOTDIR "/usr/local/share"
|
|
||||||
#define DATADIR "/usr/local/share"
|
|
||||||
#define SYSCONFDIR "/usr/local/etc"
|
|
||||||
#define SHAREDSTATEDIR "/usr/local/com"
|
|
||||||
#define LOCALSTATEDIR "/usr/local/var"
|
|
||||||
#define INCLUDEDIR "/usr/local/include"
|
|
||||||
#define OLDINCLUDEDIR "/usr/include"
|
|
||||||
#define DOCDIR "/usr/local/share/doc/findutils"
|
|
||||||
#define INFODIR "/usr/local/share/info"
|
|
||||||
#define HTMLDIR "/usr/local/share/doc/findutils"
|
|
||||||
#define DVIDIR "/usr/local/share/doc/findutils"
|
|
||||||
#define PDFDIR "/usr/local/share/doc/findutils"
|
|
||||||
#define PSDIR "/usr/local/share/doc/findutils"
|
|
||||||
#define LIBDIR "/usr/local/lib"
|
|
||||||
#define LOCALEDIR "/usr/local/share/locale"
|
|
||||||
#define MANDIR "/usr/local/share/man"
|
|
||||||
#define PKGDATADIR "/usr/local/share/findutils"
|
|
||||||
#define PKGINCLUDEDIR "/usr/local/include/findutils"
|
|
||||||
#define PKGLIBDIR "/usr/local/lib/findutils"
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/* Invoke creat, but avoid some glitches.
|
|
||||||
|
|
||||||
Copyright (C) 2005, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "fcntl-safer.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "unistd-safer.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
creat_safer (char const *file, mode_t mode)
|
|
||||||
{
|
|
||||||
return fd_safer (creat (file, mode));
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/* Wrapper around <dirent.h>.
|
|
||||||
Copyright (C) 2006-2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef _GL_DIRENT_H
|
|
||||||
|
|
||||||
/* The include_next requires a split double-inclusion guard. */
|
|
||||||
#@INCLUDE_NEXT@ @NEXT_DIRENT_H@
|
|
||||||
|
|
||||||
#ifndef _GL_DIRENT_H
|
|
||||||
#define _GL_DIRENT_H
|
|
||||||
|
|
||||||
|
|
||||||
/* Declare overridden functions. */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if @REPLACE_FCHDIR@
|
|
||||||
# define opendir rpl_opendir
|
|
||||||
extern DIR * opendir (const char *);
|
|
||||||
# define closedir rpl_closedir
|
|
||||||
extern int closedir (DIR *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _GL_DIRENT_H */
|
|
||||||
#endif /* _GL_DIRENT_H */
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/* dirfd.c -- return the file descriptor associated with an open DIR*
|
|
||||||
|
|
||||||
Copyright (C) 2001, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "dirfd.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
dirfd (DIR const *dir_p)
|
|
||||||
{
|
|
||||||
return DIR_TO_FD (dir_p);
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/* Declare dirfd, if necessary.
|
|
||||||
Copyright (C) 2001, 2002, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#ifndef HAVE_DECL_DIRFD
|
|
||||||
"this configure-time declaration test was not run"
|
|
||||||
#endif
|
|
||||||
#if !HAVE_DECL_DIRFD && !defined dirfd
|
|
||||||
int dirfd (DIR const *);
|
|
||||||
#endif
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/* dirname.c -- return all but the last element in a file name
|
|
||||||
|
|
||||||
Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "dirname.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "xalloc.h"
|
|
||||||
|
|
||||||
/* Return the length of the prefix of FILE that will be used by
|
|
||||||
dir_name. If FILE is in the working directory, this returns zero
|
|
||||||
even though `dir_name (FILE)' will return ".". Works properly even
|
|
||||||
if there are trailing slashes (by effectively ignoring them). */
|
|
||||||
|
|
||||||
size_t
|
|
||||||
dir_len (char const *file)
|
|
||||||
{
|
|
||||||
size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file);
|
|
||||||
size_t length;
|
|
||||||
|
|
||||||
/* Advance prefix_length beyond important leading slashes. */
|
|
||||||
prefix_length += (prefix_length != 0
|
|
||||||
? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
|
||||||
&& ISSLASH (file[prefix_length]))
|
|
||||||
: (ISSLASH (file[0])
|
|
||||||
? ((DOUBLE_SLASH_IS_DISTINCT_ROOT
|
|
||||||
&& ISSLASH (file[1]) && ! ISSLASH (file[2])
|
|
||||||
? 2 : 1))
|
|
||||||
: 0));
|
|
||||||
|
|
||||||
/* Strip the basename and any redundant slashes before it. */
|
|
||||||
for (length = last_component (file) - file;
|
|
||||||
prefix_length < length; length--)
|
|
||||||
if (! ISSLASH (file[length - 1]))
|
|
||||||
break;
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* In general, we can't use the builtin `dirname' function if available,
|
|
||||||
since it has different meanings in different environments.
|
|
||||||
In some environments the builtin `dirname' modifies its argument.
|
|
||||||
|
|
||||||
Return the leading directories part of FILE, allocated with xmalloc.
|
|
||||||
Works properly even if there are trailing slashes (by effectively
|
|
||||||
ignoring them). Unlike POSIX dirname(), FILE cannot be NULL.
|
|
||||||
|
|
||||||
If lstat (FILE) would succeed, then { chdir (dir_name (FILE));
|
|
||||||
lstat (base_name (FILE)); } will access the same file. Likewise,
|
|
||||||
if the sequence { chdir (dir_name (FILE));
|
|
||||||
rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE
|
|
||||||
to "foo" in the same directory FILE was in. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
dir_name (char const *file)
|
|
||||||
{
|
|
||||||
size_t length = dir_len (file);
|
|
||||||
bool append_dot = (length == 0
|
|
||||||
|| (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
|
||||||
&& length == FILE_SYSTEM_PREFIX_LEN (file)
|
|
||||||
&& file[2] != '\0' && ! ISSLASH (file[2])));
|
|
||||||
char *dir = xmalloc (length + append_dot + 1);
|
|
||||||
memcpy (dir, file, length);
|
|
||||||
if (append_dot)
|
|
||||||
dir[length++] = '.';
|
|
||||||
dir[length] = '\0';
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
/* Take file names apart into directory and base names.
|
|
||||||
|
|
||||||
Copyright (C) 1998, 2001, 2003-2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef DIRNAME_H_
|
|
||||||
# define DIRNAME_H_ 1
|
|
||||||
|
|
||||||
# include <stdbool.h>
|
|
||||||
# include <stddef.h>
|
|
||||||
|
|
||||||
# ifndef DIRECTORY_SEPARATOR
|
|
||||||
# define DIRECTORY_SEPARATOR '/'
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef ISSLASH
|
|
||||||
# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef FILE_SYSTEM_PREFIX_LEN
|
|
||||||
# if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
|
|
||||||
/* This internal macro assumes ASCII, but all hosts that support drive
|
|
||||||
letters use ASCII. */
|
|
||||||
# define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \
|
|
||||||
<= 'z' - 'a')
|
|
||||||
# define FILE_SYSTEM_PREFIX_LEN(Filename) \
|
|
||||||
(_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0)
|
|
||||||
# else
|
|
||||||
# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
|
||||||
# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
|
|
||||||
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
|
||||||
# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
|
|
||||||
# else
|
|
||||||
# define IS_ABSOLUTE_FILE_NAME(F) \
|
|
||||||
(ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F))
|
|
||||||
# endif
|
|
||||||
# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
|
|
||||||
|
|
||||||
char *base_name (char const *file);
|
|
||||||
char *dir_name (char const *file);
|
|
||||||
size_t base_len (char const *file);
|
|
||||||
size_t dir_len (char const *file);
|
|
||||||
char *last_component (char const *file);
|
|
||||||
|
|
||||||
bool strip_trailing_slashes (char *file);
|
|
||||||
|
|
||||||
#endif /* not DIRNAME_H_ */
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/* Invoke dup, but avoid some glitches.
|
|
||||||
|
|
||||||
Copyright (C) 2001, 2004, 2005, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "unistd-safer.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#ifndef STDERR_FILENO
|
|
||||||
# define STDERR_FILENO 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Like dup, but do not return STDIN_FILENO, STDOUT_FILENO, or
|
|
||||||
STDERR_FILENO. */
|
|
||||||
|
|
||||||
int
|
|
||||||
dup_safer (int fd)
|
|
||||||
{
|
|
||||||
#if defined F_DUPFD && !defined FCHDIR_REPLACEMENT
|
|
||||||
return fcntl (fd, F_DUPFD, STDERR_FILENO + 1);
|
|
||||||
#else
|
|
||||||
/* fd_safer calls us back, but eventually the recursion unwinds and
|
|
||||||
does the right thing. */
|
|
||||||
return fd_safer (dup (fd));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/* Duplicate an open file descriptor to a specified file descriptor.
|
|
||||||
|
|
||||||
Copyright (C) 1999, 2004, 2005, 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Paul Eggert */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
}
|
|
||||||
@@ -1,338 +0,0 @@
|
|||||||
/* Error handler for noninteractive utilities
|
|
||||||
Copyright (C) 1990-1998, 2000-2007 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by David MacKenzie <[email protected]>. */
|
|
||||||
|
|
||||||
#if !_LIBC
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "error.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#if !_LIBC && ENABLE_NLS
|
|
||||||
# include "gettext.h"
|
|
||||||
# define _(msgid) gettext (msgid)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
# include <libintl.h>
|
|
||||||
# include <stdbool.h>
|
|
||||||
# include <stdint.h>
|
|
||||||
# include <wchar.h>
|
|
||||||
# define mbsrtowcs __mbsrtowcs
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if USE_UNLOCKED_IO
|
|
||||||
# include "unlocked-io.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _
|
|
||||||
# define _(String) String
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If NULL, error will flush stdout, then print on stderr the program
|
|
||||||
name, a colon and a space. Otherwise, error will call this
|
|
||||||
function without parameters instead. */
|
|
||||||
void (*error_print_progname) (void);
|
|
||||||
|
|
||||||
/* This variable is incremented each time `error' is called. */
|
|
||||||
unsigned int error_message_count;
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
/* In the GNU C library, there is a predefined variable for this. */
|
|
||||||
|
|
||||||
# define program_name program_invocation_name
|
|
||||||
# include <errno.h>
|
|
||||||
# include <limits.h>
|
|
||||||
# include <libio/libioP.h>
|
|
||||||
|
|
||||||
/* In GNU libc we want do not want to use the common name `error' directly.
|
|
||||||
Instead make it a weak alias. */
|
|
||||||
extern void __error (int status, int errnum, const char *message, ...)
|
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
|
||||||
extern void __error_at_line (int status, int errnum, const char *file_name,
|
|
||||||
unsigned int line_number, const char *message,
|
|
||||||
...)
|
|
||||||
__attribute__ ((__format__ (__printf__, 5, 6)));;
|
|
||||||
# define error __error
|
|
||||||
# define error_at_line __error_at_line
|
|
||||||
|
|
||||||
# include <libio/iolibio.h>
|
|
||||||
# define fflush(s) INTUSE(_IO_fflush) (s)
|
|
||||||
# undef putc
|
|
||||||
# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
|
|
||||||
|
|
||||||
# include <bits/libc-lock.h>
|
|
||||||
|
|
||||||
#else /* not _LIBC */
|
|
||||||
|
|
||||||
# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
|
|
||||||
# ifndef HAVE_DECL_STRERROR_R
|
|
||||||
"this configure-time declaration test was not run"
|
|
||||||
# endif
|
|
||||||
char *strerror_r ();
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* The calling program should define program_name and set it to the
|
|
||||||
name of the executing program. */
|
|
||||||
extern char *program_name;
|
|
||||||
|
|
||||||
# if HAVE_STRERROR_R || defined strerror_r
|
|
||||||
# define __strerror_r strerror_r
|
|
||||||
# endif /* HAVE_STRERROR_R || defined strerror_r */
|
|
||||||
#endif /* not _LIBC */
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_errno_message (int errnum)
|
|
||||||
{
|
|
||||||
char const *s;
|
|
||||||
|
|
||||||
#if defined HAVE_STRERROR_R || _LIBC
|
|
||||||
char errbuf[1024];
|
|
||||||
# if STRERROR_R_CHAR_P || _LIBC
|
|
||||||
s = __strerror_r (errnum, errbuf, sizeof errbuf);
|
|
||||||
# else
|
|
||||||
if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
|
|
||||||
s = errbuf;
|
|
||||||
else
|
|
||||||
s = 0;
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
s = strerror (errnum);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !_LIBC
|
|
||||||
if (! s)
|
|
||||||
s = _("Unknown system error");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if _LIBC
|
|
||||||
__fxprintf (NULL, ": %s", s);
|
|
||||||
#else
|
|
||||||
fprintf (stderr, ": %s", s);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
error_tail (int status, int errnum, const char *message, va_list args)
|
|
||||||
{
|
|
||||||
#if _LIBC
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
|
||||||
{
|
|
||||||
# define ALLOCA_LIMIT 2000
|
|
||||||
size_t len = strlen (message) + 1;
|
|
||||||
wchar_t *wmessage = NULL;
|
|
||||||
mbstate_t st;
|
|
||||||
size_t res;
|
|
||||||
const char *tmp;
|
|
||||||
bool use_malloc = false;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (__libc_use_alloca (len * sizeof (wchar_t)))
|
|
||||||
wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!use_malloc)
|
|
||||||
wmessage = NULL;
|
|
||||||
|
|
||||||
wchar_t *p = (wchar_t *) realloc (wmessage,
|
|
||||||
len * sizeof (wchar_t));
|
|
||||||
if (p == NULL)
|
|
||||||
{
|
|
||||||
free (wmessage);
|
|
||||||
fputws_unlocked (L"out of memory\n", stderr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wmessage = p;
|
|
||||||
use_malloc = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset (&st, '\0', sizeof (st));
|
|
||||||
tmp = message;
|
|
||||||
|
|
||||||
res = mbsrtowcs (wmessage, &tmp, len, &st);
|
|
||||||
if (res != len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (__builtin_expect (len >= SIZE_MAX / 2, 0))
|
|
||||||
{
|
|
||||||
/* This really should not happen if everything is fine. */
|
|
||||||
res = (size_t) -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
len *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == (size_t) -1)
|
|
||||||
{
|
|
||||||
/* The string cannot be converted. */
|
|
||||||
if (use_malloc)
|
|
||||||
{
|
|
||||||
free (wmessage);
|
|
||||||
use_malloc = false;
|
|
||||||
}
|
|
||||||
wmessage = (wchar_t *) L"???";
|
|
||||||
}
|
|
||||||
|
|
||||||
__vfwprintf (stderr, wmessage, args);
|
|
||||||
|
|
||||||
if (use_malloc)
|
|
||||||
free (wmessage);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
vfprintf (stderr, message, args);
|
|
||||||
va_end (args);
|
|
||||||
|
|
||||||
++error_message_count;
|
|
||||||
if (errnum)
|
|
||||||
print_errno_message (errnum);
|
|
||||||
#if _LIBC
|
|
||||||
__fxprintf (NULL, "\n");
|
|
||||||
#else
|
|
||||||
putc ('\n', stderr);
|
|
||||||
#endif
|
|
||||||
fflush (stderr);
|
|
||||||
if (status)
|
|
||||||
exit (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Print the program name and error message MESSAGE, which is a printf-style
|
|
||||||
format string with optional args.
|
|
||||||
If ERRNUM is nonzero, print its corresponding system error message.
|
|
||||||
Exit with status STATUS if it is nonzero. */
|
|
||||||
void
|
|
||||||
error (int status, int errnum, const char *message, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
#if defined _LIBC && defined __libc_ptf_call
|
|
||||||
/* We do not want this call to be cut short by a thread
|
|
||||||
cancellation. Therefore disable cancellation for now. */
|
|
||||||
int state = PTHREAD_CANCEL_ENABLE;
|
|
||||||
__libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
|
|
||||||
0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fflush (stdout);
|
|
||||||
#ifdef _LIBC
|
|
||||||
_IO_flockfile (stderr);
|
|
||||||
#endif
|
|
||||||
if (error_print_progname)
|
|
||||||
(*error_print_progname) ();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if _LIBC
|
|
||||||
__fxprintf (NULL, "%s: ", program_name);
|
|
||||||
#else
|
|
||||||
fprintf (stderr, "%s: ", program_name);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start (args, message);
|
|
||||||
error_tail (status, errnum, message, args);
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
_IO_funlockfile (stderr);
|
|
||||||
# ifdef __libc_ptf_call
|
|
||||||
__libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sometimes we want to have at most one error per line. This
|
|
||||||
variable controls whether this mode is selected or not. */
|
|
||||||
int error_one_per_line;
|
|
||||||
|
|
||||||
void
|
|
||||||
error_at_line (int status, int errnum, const char *file_name,
|
|
||||||
unsigned int line_number, const char *message, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
if (error_one_per_line)
|
|
||||||
{
|
|
||||||
static const char *old_file_name;
|
|
||||||
static unsigned int old_line_number;
|
|
||||||
|
|
||||||
if (old_line_number == line_number
|
|
||||||
&& (file_name == old_file_name
|
|
||||||
|| strcmp (old_file_name, file_name) == 0))
|
|
||||||
/* Simply return and print nothing. */
|
|
||||||
return;
|
|
||||||
|
|
||||||
old_file_name = file_name;
|
|
||||||
old_line_number = line_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined _LIBC && defined __libc_ptf_call
|
|
||||||
/* We do not want this call to be cut short by a thread
|
|
||||||
cancellation. Therefore disable cancellation for now. */
|
|
||||||
int state = PTHREAD_CANCEL_ENABLE;
|
|
||||||
__libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
|
|
||||||
0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fflush (stdout);
|
|
||||||
#ifdef _LIBC
|
|
||||||
_IO_flockfile (stderr);
|
|
||||||
#endif
|
|
||||||
if (error_print_progname)
|
|
||||||
(*error_print_progname) ();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if _LIBC
|
|
||||||
__fxprintf (NULL, "%s:", program_name);
|
|
||||||
#else
|
|
||||||
fprintf (stderr, "%s:", program_name);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if _LIBC
|
|
||||||
__fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
|
|
||||||
file_name, line_number);
|
|
||||||
#else
|
|
||||||
fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
|
|
||||||
file_name, line_number);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
va_start (args, message);
|
|
||||||
error_tail (status, errnum, message, args);
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
_IO_funlockfile (stderr);
|
|
||||||
# ifdef __libc_ptf_call
|
|
||||||
__libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
/* Make the weak alias. */
|
|
||||||
# undef error
|
|
||||||
# undef error_at_line
|
|
||||||
weak_alias (__error, error)
|
|
||||||
weak_alias (__error_at_line, error_at_line)
|
|
||||||
#endif
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/* Declaration for error-reporting function
|
|
||||||
Copyright (C) 1995, 1996, 1997, 2003, 2006 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef _ERROR_H
|
|
||||||
#define _ERROR_H 1
|
|
||||||
|
|
||||||
#ifndef __attribute__
|
|
||||||
/* This feature is available in gcc versions 2.5 and later. */
|
|
||||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
|
|
||||||
# define __attribute__(Spec) /* empty */
|
|
||||||
# endif
|
|
||||||
/* The __-protected variants of `format' and `printf' attributes
|
|
||||||
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
|
|
||||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
|
|
||||||
# define __format__ format
|
|
||||||
# define __printf__ printf
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Print a message with `fprintf (stderr, FORMAT, ...)';
|
|
||||||
if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
|
|
||||||
If STATUS is nonzero, terminate the program with `exit (STATUS)'. */
|
|
||||||
|
|
||||||
extern void error (int __status, int __errnum, const char *__format, ...)
|
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
|
||||||
|
|
||||||
extern void error_at_line (int __status, int __errnum, const char *__fname,
|
|
||||||
unsigned int __lineno, const char *__format, ...)
|
|
||||||
__attribute__ ((__format__ (__printf__, 5, 6)));
|
|
||||||
|
|
||||||
/* If NULL, error will flush stdout, then print on stderr the program
|
|
||||||
name, a colon and a space. Otherwise, error will call this
|
|
||||||
function without parameters instead. */
|
|
||||||
extern void (*error_print_progname) (void);
|
|
||||||
|
|
||||||
/* This variable is incremented each time `error' is called. */
|
|
||||||
extern unsigned int error_message_count;
|
|
||||||
|
|
||||||
/* Sometimes we want to have at most one error per line. This
|
|
||||||
variable controls whether this mode is selected or not. */
|
|
||||||
extern int error_one_per_line;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* error.h */
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/* Failure exit status
|
|
||||||
|
|
||||||
Copyright (C) 2002, 2003, 2005, 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "exitfail.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int volatile exit_failure = EXIT_FAILURE;
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
/* Failure exit status
|
|
||||||
|
|
||||||
Copyright (C) 2002 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
extern int volatile exit_failure;
|
|
||||||
@@ -1,282 +0,0 @@
|
|||||||
/* fchdir replacement.
|
|
||||||
Copyright (C) 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#include "canonicalize.h"
|
|
||||||
#include "dirfd.h"
|
|
||||||
|
|
||||||
/* This replacement assumes that a directory is not renamed while opened
|
|
||||||
through a file descriptor. */
|
|
||||||
|
|
||||||
/* Array of file descriptors opened. If it points to a directory, it stores
|
|
||||||
info about this directory; otherwise it stores an errno value of ENOTDIR. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char *name; /* Absolute name of the directory, or NULL. */
|
|
||||||
int saved_errno; /* If name == NULL: The error code describing the failure
|
|
||||||
reason. */
|
|
||||||
} dir_info_t;
|
|
||||||
static dir_info_t *dirs;
|
|
||||||
static size_t dirs_allocated;
|
|
||||||
|
|
||||||
/* Try to ensure dirs has enough room for a slot at index fd. */
|
|
||||||
static void
|
|
||||||
ensure_dirs_slot (size_t fd)
|
|
||||||
{
|
|
||||||
if (fd >= dirs_allocated)
|
|
||||||
{
|
|
||||||
size_t new_allocated;
|
|
||||||
dir_info_t *new_dirs;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
new_allocated = 2 * dirs_allocated + 1;
|
|
||||||
if (new_allocated <= fd)
|
|
||||||
new_allocated = fd + 1;
|
|
||||||
new_dirs =
|
|
||||||
(dirs != NULL
|
|
||||||
? (dir_info_t *) realloc (dirs, new_allocated * sizeof (dir_info_t))
|
|
||||||
: (dir_info_t *) malloc (new_allocated * sizeof (dir_info_t)));
|
|
||||||
if (new_dirs != NULL)
|
|
||||||
{
|
|
||||||
for (i = dirs_allocated; i < new_allocated; i++)
|
|
||||||
{
|
|
||||||
new_dirs[i].name = NULL;
|
|
||||||
new_dirs[i].saved_errno = ENOTDIR;
|
|
||||||
}
|
|
||||||
dirs = new_dirs;
|
|
||||||
dirs_allocated = new_allocated;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Override open() and close(), to keep track of the open file descriptors. */
|
|
||||||
|
|
||||||
int
|
|
||||||
rpl_close (int fd)
|
|
||||||
#undef close
|
|
||||||
{
|
|
||||||
int retval = close (fd);
|
|
||||||
|
|
||||||
if (retval >= 0 && fd >= 0 && fd < dirs_allocated)
|
|
||||||
{
|
|
||||||
if (dirs[fd].name != NULL)
|
|
||||||
free (dirs[fd].name);
|
|
||||||
dirs[fd].name = NULL;
|
|
||||||
dirs[fd].saved_errno = ENOTDIR;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
rpl_open (const char *filename, int flags, ...)
|
|
||||||
#undef open
|
|
||||||
{
|
|
||||||
mode_t mode;
|
|
||||||
int fd;
|
|
||||||
struct stat statbuf;
|
|
||||||
|
|
||||||
mode = 0;
|
|
||||||
if (flags & O_CREAT)
|
|
||||||
{
|
|
||||||
va_list arg;
|
|
||||||
va_start (arg, flags);
|
|
||||||
|
|
||||||
/* If mode_t is narrower than int, use the promoted type (int),
|
|
||||||
not mode_t. Use sizeof to guess whether mode_t is narrower;
|
|
||||||
we don't know of any practical counterexamples. */
|
|
||||||
mode = (sizeof (mode_t) < sizeof (int)
|
|
||||||
? va_arg (arg, int)
|
|
||||||
: va_arg (arg, mode_t));
|
|
||||||
|
|
||||||
va_end (arg);
|
|
||||||
}
|
|
||||||
#if defined GNULIB_OPEN && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
|
|
||||||
if (strcmp (filename, "/dev/null") == 0)
|
|
||||||
filename = "NUL";
|
|
||||||
#endif
|
|
||||||
fd = open (filename, flags, mode);
|
|
||||||
if (fd >= 0)
|
|
||||||
{
|
|
||||||
ensure_dirs_slot (fd);
|
|
||||||
if (fd < dirs_allocated
|
|
||||||
&& fstat (fd, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
|
|
||||||
{
|
|
||||||
dirs[fd].name = canonicalize_file_name (filename);
|
|
||||||
if (dirs[fd].name == NULL)
|
|
||||||
dirs[fd].saved_errno = errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Override opendir() and closedir(), to keep track of the open file
|
|
||||||
descriptors. Needed because there is a function dirfd(). */
|
|
||||||
|
|
||||||
int
|
|
||||||
rpl_closedir (DIR *dp)
|
|
||||||
#undef closedir
|
|
||||||
{
|
|
||||||
int fd = dirfd (dp);
|
|
||||||
int retval = closedir (dp);
|
|
||||||
|
|
||||||
if (retval >= 0 && fd >= 0 && fd < dirs_allocated)
|
|
||||||
{
|
|
||||||
if (dirs[fd].name != NULL)
|
|
||||||
free (dirs[fd].name);
|
|
||||||
dirs[fd].name = NULL;
|
|
||||||
dirs[fd].saved_errno = ENOTDIR;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIR *
|
|
||||||
rpl_opendir (const char *filename)
|
|
||||||
#undef opendir
|
|
||||||
{
|
|
||||||
DIR *dp;
|
|
||||||
|
|
||||||
dp = opendir (filename);
|
|
||||||
if (dp != NULL)
|
|
||||||
{
|
|
||||||
int fd = dirfd (dp);
|
|
||||||
if (fd >= 0)
|
|
||||||
{
|
|
||||||
ensure_dirs_slot (fd);
|
|
||||||
if (fd < dirs_allocated)
|
|
||||||
{
|
|
||||||
dirs[fd].name = canonicalize_file_name (filename);
|
|
||||||
if (dirs[fd].name == NULL)
|
|
||||||
dirs[fd].saved_errno = errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Override dup() and dup2(), to keep track of open file descriptors. */
|
|
||||||
|
|
||||||
int
|
|
||||||
rpl_dup (int oldfd)
|
|
||||||
#undef dup
|
|
||||||
{
|
|
||||||
int newfd = dup (oldfd);
|
|
||||||
|
|
||||||
if (oldfd >= 0 && newfd >= 0)
|
|
||||||
{
|
|
||||||
ensure_dirs_slot (newfd);
|
|
||||||
if (newfd < dirs_allocated)
|
|
||||||
{
|
|
||||||
if (oldfd < dirs_allocated)
|
|
||||||
{
|
|
||||||
if (dirs[oldfd].name != NULL)
|
|
||||||
{
|
|
||||||
dirs[newfd].name = strdup (dirs[oldfd].name);
|
|
||||||
if (dirs[newfd].name == NULL)
|
|
||||||
dirs[newfd].saved_errno = ENOMEM;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dirs[newfd].name = NULL;
|
|
||||||
dirs[newfd].saved_errno = dirs[oldfd].saved_errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dirs[newfd].name = NULL;
|
|
||||||
dirs[newfd].saved_errno = ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newfd;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
rpl_dup2 (int oldfd, int newfd)
|
|
||||||
#undef dup2
|
|
||||||
{
|
|
||||||
int retval = dup2 (oldfd, newfd);
|
|
||||||
|
|
||||||
if (retval >= 0 && oldfd >= 0 && newfd >= 0 && newfd != oldfd)
|
|
||||||
{
|
|
||||||
ensure_dirs_slot (newfd);
|
|
||||||
if (newfd < dirs_allocated)
|
|
||||||
{
|
|
||||||
if (oldfd < dirs_allocated)
|
|
||||||
{
|
|
||||||
if (dirs[oldfd].name != NULL)
|
|
||||||
{
|
|
||||||
dirs[newfd].name = strdup (dirs[oldfd].name);
|
|
||||||
if (dirs[newfd].name == NULL)
|
|
||||||
dirs[newfd].saved_errno = ENOMEM;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dirs[newfd].name = NULL;
|
|
||||||
dirs[newfd].saved_errno = dirs[oldfd].saved_errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dirs[newfd].name = NULL;
|
|
||||||
dirs[newfd].saved_errno = ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Implement fchdir() in terms of chdir(). */
|
|
||||||
|
|
||||||
int
|
|
||||||
fchdir (int fd)
|
|
||||||
{
|
|
||||||
if (fd >= 0)
|
|
||||||
{
|
|
||||||
if (fd < dirs_allocated)
|
|
||||||
{
|
|
||||||
if (dirs[fd].name != NULL)
|
|
||||||
return chdir (dirs[fd].name);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errno = dirs[fd].saved_errno;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errno = EBADF;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/* Change the protections of file relative to an open directory.
|
|
||||||
Copyright (C) 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Jim Meyering */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "openat.h"
|
|
||||||
#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
|
|
||||||
#include "save-cwd.h"
|
|
||||||
#include "openat-priv.h"
|
|
||||||
|
|
||||||
#ifndef HAVE_LCHMOD
|
|
||||||
/* Use a different name, to avoid conflicting with any
|
|
||||||
system-supplied declaration. */
|
|
||||||
# undef lchmod
|
|
||||||
# define lchmod lchmod_rpl
|
|
||||||
static int lchmod (char const *f, mode_t m) { errno = ENOSYS; return -1; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Solaris 10 has no function like this.
|
|
||||||
Invoke chmod or lchmod on file, FILE, using mode MODE, in the directory
|
|
||||||
open on descriptor FD. If possible, do it without changing the
|
|
||||||
working directory. Otherwise, resort to using save_cwd/fchdir,
|
|
||||||
then mkdir/restore_cwd. If either the save_cwd or the restore_cwd
|
|
||||||
fails, then give a diagnostic and exit nonzero.
|
|
||||||
Note that an attempt to use a FLAG value of AT_SYMLINK_NOFOLLOW
|
|
||||||
on a system without lchmod support causes this function to fail. */
|
|
||||||
|
|
||||||
#define AT_FUNC_NAME fchmodat
|
|
||||||
#define AT_FUNC_F1 lchmod
|
|
||||||
#define AT_FUNC_F2 chmod
|
|
||||||
#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW
|
|
||||||
#define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode, int flag
|
|
||||||
#define AT_FUNC_POST_FILE_ARGS , mode
|
|
||||||
#include "at-func.c"
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/* A trivial substitute for `fchown'.
|
|
||||||
|
|
||||||
DJGPP 2.03 and earlier (and perhaps later) don't have `fchown',
|
|
||||||
so we pretend no-one has permission for this operation. */
|
|
||||||
|
|
||||||
int
|
|
||||||
fchown (int fd, uid_t uid, gid_t gid)
|
|
||||||
{
|
|
||||||
errno = EPERM;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/* This function serves as replacement for a missing fchownat function,
|
|
||||||
as well as a work around for the fchownat bug in glibc-2.4:
|
|
||||||
<http://lists.ubuntu.com/archives/ubuntu-users/2006-September/093218.html>
|
|
||||||
when the buggy fchownat-with-AT_SYMLINK_NOFOLLOW operates on a symlink, it
|
|
||||||
mistakenly affects the symlink referent, rather than the symlink itself.
|
|
||||||
|
|
||||||
Copyright (C) 2006-2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Jim Meyering */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "openat.h"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
|
|
||||||
#include "save-cwd.h"
|
|
||||||
#include "openat-priv.h"
|
|
||||||
|
|
||||||
/* Replacement for Solaris' function by the same name.
|
|
||||||
Invoke chown or lchown on file, FILE, using OWNER and GROUP, in the
|
|
||||||
directory open on descriptor FD. If FLAG is AT_SYMLINK_NOFOLLOW, then
|
|
||||||
use lchown, otherwise, use chown. If possible, do it without changing
|
|
||||||
the working directory. Otherwise, resort to using save_cwd/fchdir,
|
|
||||||
then mkdir/restore_cwd. If either the save_cwd or the restore_cwd
|
|
||||||
fails, then give a diagnostic and exit nonzero. */
|
|
||||||
|
|
||||||
#define AT_FUNC_NAME fchownat
|
|
||||||
#define AT_FUNC_F1 lchown
|
|
||||||
#define AT_FUNC_F2 chown
|
|
||||||
#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW
|
|
||||||
#define AT_FUNC_POST_FILE_PARAM_DECLS , uid_t owner, gid_t group, int flag
|
|
||||||
#define AT_FUNC_POST_FILE_ARGS , owner, group
|
|
||||||
#include "at-func.c"
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/* Like fcntl.h, but redefine some names to avoid glitches.
|
|
||||||
|
|
||||||
Copyright (C) 2005 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert. */
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "fcntl-safer.h"
|
|
||||||
|
|
||||||
#undef open
|
|
||||||
#define open open_safer
|
|
||||||
|
|
||||||
#undef creat
|
|
||||||
#define creat creat_safer
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/* Invoke fcntl-like functions, but avoid some glitches.
|
|
||||||
|
|
||||||
Copyright (C) 2005 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert. */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
int open_safer (char const *, int, ...);
|
|
||||||
int creat_safer (char const *, mode_t);
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
|
||||||
/* Like <fcntl.h>, but with non-working flags defined to 0.
|
|
||||||
|
|
||||||
Copyright (C) 2006-2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Paul Eggert */
|
|
||||||
|
|
||||||
#ifndef _GL_FCNTL_H
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
/* The include_next requires a split double-inclusion guard. */
|
|
||||||
#include_next <fcntl.h>
|
|
||||||
|
|
||||||
#ifndef _GL_FCNTL_H
|
|
||||||
#define _GL_FCNTL_H
|
|
||||||
|
|
||||||
|
|
||||||
/* Declare overridden functions. */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (0 && 0) || defined FCHDIR_REPLACEMENT
|
|
||||||
# define open rpl_open
|
|
||||||
extern int open (const char *filename, int flags, ...);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Fix up the O_* macros. */
|
|
||||||
|
|
||||||
#if !defined O_DIRECT && defined O_DIRECTIO
|
|
||||||
/* Tru64 spells it `O_DIRECTIO'. */
|
|
||||||
# define O_DIRECT O_DIRECTIO
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_DIRECT
|
|
||||||
# define O_DIRECT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_DIRECTORY
|
|
||||||
# define O_DIRECTORY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_DSYNC
|
|
||||||
# define O_DSYNC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NDELAY
|
|
||||||
# define O_NDELAY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NOATIME
|
|
||||||
# define O_NOATIME 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NONBLOCK
|
|
||||||
# define O_NONBLOCK O_NDELAY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NOCTTY
|
|
||||||
# define O_NOCTTY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NOFOLLOW
|
|
||||||
# define O_NOFOLLOW 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NOLINKS
|
|
||||||
# define O_NOLINKS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_RSYNC
|
|
||||||
# define O_RSYNC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_SYNC
|
|
||||||
# define O_SYNC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* For systems that distinguish between text and binary I/O.
|
|
||||||
O_BINARY is usually declared in fcntl.h */
|
|
||||||
#if !defined O_BINARY && defined _O_BINARY
|
|
||||||
/* For MSC-compatible compilers. */
|
|
||||||
# define O_BINARY _O_BINARY
|
|
||||||
# define O_TEXT _O_TEXT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __BEOS__
|
|
||||||
/* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */
|
|
||||||
# undef O_BINARY
|
|
||||||
# undef O_TEXT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_BINARY
|
|
||||||
# define O_BINARY 0
|
|
||||||
# define O_TEXT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _GL_FCNTL_H */
|
|
||||||
#endif /* _GL_FCNTL_H */
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
/* Like <fcntl.h>, but with non-working flags defined to 0.
|
|
||||||
|
|
||||||
Copyright (C) 2006-2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Paul Eggert */
|
|
||||||
|
|
||||||
#ifndef _GL_FCNTL_H
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
/* The include_next requires a split double-inclusion guard. */
|
|
||||||
#@INCLUDE_NEXT@ @NEXT_FCNTL_H@
|
|
||||||
|
|
||||||
#ifndef _GL_FCNTL_H
|
|
||||||
#define _GL_FCNTL_H
|
|
||||||
|
|
||||||
|
|
||||||
/* Declare overridden functions. */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (@GNULIB_OPEN@ && @REPLACE_OPEN@) || defined FCHDIR_REPLACEMENT
|
|
||||||
# define open rpl_open
|
|
||||||
extern int open (const char *filename, int flags, ...);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Fix up the O_* macros. */
|
|
||||||
|
|
||||||
#if !defined O_DIRECT && defined O_DIRECTIO
|
|
||||||
/* Tru64 spells it `O_DIRECTIO'. */
|
|
||||||
# define O_DIRECT O_DIRECTIO
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_DIRECT
|
|
||||||
# define O_DIRECT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_DIRECTORY
|
|
||||||
# define O_DIRECTORY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_DSYNC
|
|
||||||
# define O_DSYNC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NDELAY
|
|
||||||
# define O_NDELAY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NOATIME
|
|
||||||
# define O_NOATIME 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NONBLOCK
|
|
||||||
# define O_NONBLOCK O_NDELAY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NOCTTY
|
|
||||||
# define O_NOCTTY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NOFOLLOW
|
|
||||||
# define O_NOFOLLOW 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NOLINKS
|
|
||||||
# define O_NOLINKS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_RSYNC
|
|
||||||
# define O_RSYNC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_SYNC
|
|
||||||
# define O_SYNC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* For systems that distinguish between text and binary I/O.
|
|
||||||
O_BINARY is usually declared in fcntl.h */
|
|
||||||
#if !defined O_BINARY && defined _O_BINARY
|
|
||||||
/* For MSC-compatible compilers. */
|
|
||||||
# define O_BINARY _O_BINARY
|
|
||||||
# define O_TEXT _O_TEXT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __BEOS__
|
|
||||||
/* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */
|
|
||||||
# undef O_BINARY
|
|
||||||
# undef O_TEXT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_BINARY
|
|
||||||
# define O_BINARY 0
|
|
||||||
# define O_TEXT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _GL_FCNTL_H */
|
|
||||||
#endif /* _GL_FCNTL_H */
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/* Return a safer copy of a file descriptor.
|
|
||||||
|
|
||||||
Copyright (C) 2005, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "unistd-safer.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#ifndef STDIN_FILENO
|
|
||||||
# define STDIN_FILENO 0
|
|
||||||
#endif
|
|
||||||
#ifndef STDERR_FILENO
|
|
||||||
# define STDERR_FILENO 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Return FD, unless FD would be a copy of standard input, output, or
|
|
||||||
error; in that case, return a duplicate of FD, closing FD. On
|
|
||||||
failure to duplicate, close FD, set errno, and return -1. Preserve
|
|
||||||
errno if FD is negative, so that the caller can always inspect
|
|
||||||
errno when the returned value is negative.
|
|
||||||
|
|
||||||
This function is usefully wrapped around functions that return file
|
|
||||||
descriptors, e.g., fd_safer (open ("file", O_RDONLY)). */
|
|
||||||
|
|
||||||
int
|
|
||||||
fd_safer (int fd)
|
|
||||||
{
|
|
||||||
if (STDIN_FILENO <= fd && fd <= STDERR_FILENO)
|
|
||||||
{
|
|
||||||
int f = dup_safer (fd);
|
|
||||||
int e = errno;
|
|
||||||
close (fd);
|
|
||||||
errno = e;
|
|
||||||
fd = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/* fflush.c -- allow flushing input streams
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Eric Blake. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "freading.h"
|
|
||||||
#include "fpurge.h"
|
|
||||||
|
|
||||||
#undef fflush
|
|
||||||
|
|
||||||
/* Flush all pending data on STREAM according to POSIX rules. Both
|
|
||||||
output and seekable input streams are supported. */
|
|
||||||
int
|
|
||||||
rpl_fflush (FILE *stream)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
off_t pos;
|
|
||||||
|
|
||||||
/* When stream is NULL, POSIX and C99 only require flushing of "output
|
|
||||||
streams and update streams in which the most recent operation was not
|
|
||||||
input", and all implementations do this.
|
|
||||||
|
|
||||||
When stream is "an output stream or an update stream in which the most
|
|
||||||
recent operation was not input", POSIX and C99 requires that fflush
|
|
||||||
writes out any buffered data, and all implementations do this.
|
|
||||||
|
|
||||||
When stream is, however, an input stream or an update stream in
|
|
||||||
which the most recent operation was input, C99 specifies nothing,
|
|
||||||
and POSIX only specifies behavior if the stream is seekable.
|
|
||||||
mingw, in particular, drops the input buffer, leaving the file
|
|
||||||
descriptor positioned at the end of the input buffer. I.e. ftell
|
|
||||||
(stream) is lost. We don't want to call the implementation's
|
|
||||||
fflush in this case.
|
|
||||||
|
|
||||||
We test ! freading (stream) here, rather than fwriting (stream), because
|
|
||||||
what we need to know is whether the stream holds a "read buffer", and on
|
|
||||||
mingw this is indicated by _IOREAD, regardless of _IOWRT. */
|
|
||||||
if (stream == NULL || ! freading (stream))
|
|
||||||
return fflush (stream);
|
|
||||||
|
|
||||||
/* POSIX does not specify fflush behavior for non-seekable input
|
|
||||||
streams. Some implementations purge unread data, some return
|
|
||||||
EBADF, some do nothing. */
|
|
||||||
pos = ftello (stream);
|
|
||||||
if (pos == -1)
|
|
||||||
{
|
|
||||||
errno = EBADF;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* To get here, we must be flushing a seekable input stream, so the
|
|
||||||
semantics of fpurge are now appropriate to clear the buffer. To
|
|
||||||
avoid losing data, the lseek is also necessary. */
|
|
||||||
result = fpurge (stream);
|
|
||||||
if (result != 0)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
#if defined __sferror && defined __SNPT /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
|
|
||||||
|
|
||||||
{
|
|
||||||
/* Disable seek optimization for the next fseeko call. This tells the
|
|
||||||
following fseeko call to seek to the desired position directly, rather
|
|
||||||
than to seek to a block-aligned boundary. */
|
|
||||||
int saved_flags = stream->_flags & (__SOPT | __SNPT);
|
|
||||||
stream->_flags = (stream->_flags & ~__SOPT) | __SNPT;
|
|
||||||
|
|
||||||
result = fseeko (stream, pos, SEEK_SET);
|
|
||||||
|
|
||||||
stream->_flags = (stream->_flags & ~(__SOPT | __SNPT)) | saved_flags;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
pos = lseek (fileno (stream), pos, SEEK_SET);
|
|
||||||
if (pos == -1)
|
|
||||||
return EOF;
|
|
||||||
/* After a successful lseek, update the file descriptor's position cache
|
|
||||||
in the stream. */
|
|
||||||
# if defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
|
|
||||||
stream->_offset = pos;
|
|
||||||
stream->_flags |= __SOFF;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/* Specialized functions to manipulate a set of files.
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Jim Meyering */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include "file-set.h"
|
|
||||||
|
|
||||||
#include "hash-triple.h"
|
|
||||||
#include "xalloc.h"
|
|
||||||
|
|
||||||
/* Record file, FILE, and dev/ino from *STATS, in the hash table, HT.
|
|
||||||
If HT is NULL, return immediately.
|
|
||||||
If memory allocation fails, exit immediately. */
|
|
||||||
void
|
|
||||||
record_file (Hash_table *ht, char const *file, struct stat const *stats)
|
|
||||||
{
|
|
||||||
struct F_triple *ent;
|
|
||||||
|
|
||||||
if (ht == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ent = xmalloc (sizeof *ent);
|
|
||||||
ent->name = xstrdup (file);
|
|
||||||
ent->st_ino = stats->st_ino;
|
|
||||||
ent->st_dev = stats->st_dev;
|
|
||||||
|
|
||||||
{
|
|
||||||
struct F_triple *ent_from_table = hash_insert (ht, ent);
|
|
||||||
if (ent_from_table == NULL)
|
|
||||||
{
|
|
||||||
/* Insertion failed due to lack of memory. */
|
|
||||||
xalloc_die ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ent_from_table != ent)
|
|
||||||
{
|
|
||||||
/* There was alread a matching entry in the table, so ENT was
|
|
||||||
not inserted. Free it. */
|
|
||||||
triple_free (ent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true if there is an entry in hash table, HT,
|
|
||||||
for the file described by FILE and STATS. */
|
|
||||||
bool
|
|
||||||
seen_file (Hash_table const *ht, char const *file,
|
|
||||||
struct stat const *stats)
|
|
||||||
{
|
|
||||||
struct F_triple new_ent;
|
|
||||||
|
|
||||||
if (ht == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
new_ent.name = (char *) file;
|
|
||||||
new_ent.st_ino = stats->st_ino;
|
|
||||||
new_ent.st_dev = stats->st_dev;
|
|
||||||
|
|
||||||
return !!hash_lookup (ht, &new_ent);
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "hash.h"
|
|
||||||
|
|
||||||
extern void record_file (Hash_table *ht, char const *file,
|
|
||||||
struct stat const *stats)
|
|
||||||
__attribute__((nonnull(2, 3)));
|
|
||||||
|
|
||||||
extern bool seen_file (Hash_table const *ht, char const *file,
|
|
||||||
struct stat const *stats);
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/* Convert file size to number of blocks on System V-like machines.
|
|
||||||
|
|
||||||
Copyright (C) 1990, 1997, 1998, 1999, 2004, 2005, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Brian L. Matthews, [email protected]. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#if HAVE_SYS_PARAM_H
|
|
||||||
# include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !HAVE_STRUCT_STAT_ST_BLOCKS && !defined _POSIX_SOURCE && defined BSIZE
|
|
||||||
|
|
||||||
# include <unistd.h>
|
|
||||||
|
|
||||||
# ifndef NINDIR
|
|
||||||
|
|
||||||
# if defined __DJGPP__
|
|
||||||
typedef long daddr_t; /* for disk address */
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Some SysV's, like Irix, seem to lack this. Hope it's correct. */
|
|
||||||
/* Number of inode pointers per indirect block. */
|
|
||||||
# define NINDIR (BSIZE / sizeof (daddr_t))
|
|
||||||
# endif /* !NINDIR */
|
|
||||||
|
|
||||||
/* Number of direct block addresses in an inode. */
|
|
||||||
# define NDIR 10
|
|
||||||
|
|
||||||
/* Return the number of 512-byte blocks in a file of SIZE bytes. */
|
|
||||||
|
|
||||||
off_t
|
|
||||||
st_blocks (off_t size)
|
|
||||||
{
|
|
||||||
off_t datablks = size / 512 + (size % 512 != 0);
|
|
||||||
off_t indrblks = 0;
|
|
||||||
|
|
||||||
if (datablks > NDIR)
|
|
||||||
{
|
|
||||||
indrblks = (datablks - NDIR - 1) / NINDIR + 1;
|
|
||||||
|
|
||||||
if (datablks > NDIR + NINDIR)
|
|
||||||
{
|
|
||||||
indrblks += (datablks - NDIR - NINDIR - 1) / (NINDIR * NINDIR) + 1;
|
|
||||||
|
|
||||||
if (datablks > NDIR + NINDIR + NINDIR * NINDIR)
|
|
||||||
indrblks++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return datablks + indrblks;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* This declaration is solely to ensure that after preprocessing
|
|
||||||
this file is never empty. */
|
|
||||||
typedef int textutils_fileblocks_unused;
|
|
||||||
#endif
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
/* filemode.c -- make a string describing file modes
|
|
||||||
|
|
||||||
Copyright (C) 1985, 1990, 1993, 1998-2000, 2004, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "filemode.h"
|
|
||||||
|
|
||||||
/* The following is for Cray DMF (Data Migration Facility), which is a
|
|
||||||
HSM file system. A migrated file has a `st_dm_mode' that is
|
|
||||||
different from the normal `st_mode', so any tests for migrated
|
|
||||||
files should use the former. */
|
|
||||||
#if HAVE_ST_DM_MODE
|
|
||||||
# define IS_MIGRATED_FILE(statp) \
|
|
||||||
(S_ISOFD (statp->st_dm_mode) || S_ISOFL (statp->st_dm_mode))
|
|
||||||
#else
|
|
||||||
# define IS_MIGRATED_FILE(statp) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! HAVE_DECL_STRMODE
|
|
||||||
|
|
||||||
/* Return a character indicating the type of file described by
|
|
||||||
file mode BITS:
|
|
||||||
'-' regular file
|
|
||||||
'b' block special file
|
|
||||||
'c' character special file
|
|
||||||
'C' high performance ("contiguous data") file
|
|
||||||
'd' directory
|
|
||||||
'D' door
|
|
||||||
'l' symbolic link
|
|
||||||
'm' multiplexed file (7th edition Unix; obsolete)
|
|
||||||
'n' network special file (HP-UX)
|
|
||||||
'p' fifo (named pipe)
|
|
||||||
'P' port
|
|
||||||
's' socket
|
|
||||||
'w' whiteout (4.4BSD)
|
|
||||||
'?' some other file type */
|
|
||||||
|
|
||||||
static char
|
|
||||||
ftypelet (mode_t bits)
|
|
||||||
{
|
|
||||||
/* These are the most common, so test for them first. */
|
|
||||||
if (S_ISREG (bits))
|
|
||||||
return '-';
|
|
||||||
if (S_ISDIR (bits))
|
|
||||||
return 'd';
|
|
||||||
|
|
||||||
/* Other letters standardized by POSIX 1003.1-2004. */
|
|
||||||
if (S_ISBLK (bits))
|
|
||||||
return 'b';
|
|
||||||
if (S_ISCHR (bits))
|
|
||||||
return 'c';
|
|
||||||
if (S_ISLNK (bits))
|
|
||||||
return 'l';
|
|
||||||
if (S_ISFIFO (bits))
|
|
||||||
return 'p';
|
|
||||||
|
|
||||||
/* Other file types (though not letters) standardized by POSIX. */
|
|
||||||
if (S_ISSOCK (bits))
|
|
||||||
return 's';
|
|
||||||
|
|
||||||
/* Nonstandard file types. */
|
|
||||||
if (S_ISCTG (bits))
|
|
||||||
return 'C';
|
|
||||||
if (S_ISDOOR (bits))
|
|
||||||
return 'D';
|
|
||||||
if (S_ISMPB (bits) || S_ISMPC (bits))
|
|
||||||
return 'm';
|
|
||||||
if (S_ISNWK (bits))
|
|
||||||
return 'n';
|
|
||||||
if (S_ISPORT (bits))
|
|
||||||
return 'P';
|
|
||||||
if (S_ISWHT (bits))
|
|
||||||
return 'w';
|
|
||||||
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Like filemodestring, but rely only on MODE. */
|
|
||||||
|
|
||||||
void
|
|
||||||
strmode (mode_t mode, char *str)
|
|
||||||
{
|
|
||||||
str[0] = ftypelet (mode);
|
|
||||||
str[1] = mode & S_IRUSR ? 'r' : '-';
|
|
||||||
str[2] = mode & S_IWUSR ? 'w' : '-';
|
|
||||||
str[3] = (mode & S_ISUID
|
|
||||||
? (mode & S_IXUSR ? 's' : 'S')
|
|
||||||
: (mode & S_IXUSR ? 'x' : '-'));
|
|
||||||
str[4] = mode & S_IRGRP ? 'r' : '-';
|
|
||||||
str[5] = mode & S_IWGRP ? 'w' : '-';
|
|
||||||
str[6] = (mode & S_ISGID
|
|
||||||
? (mode & S_IXGRP ? 's' : 'S')
|
|
||||||
: (mode & S_IXGRP ? 'x' : '-'));
|
|
||||||
str[7] = mode & S_IROTH ? 'r' : '-';
|
|
||||||
str[8] = mode & S_IWOTH ? 'w' : '-';
|
|
||||||
str[9] = (mode & S_ISVTX
|
|
||||||
? (mode & S_IXOTH ? 't' : 'T')
|
|
||||||
: (mode & S_IXOTH ? 'x' : '-'));
|
|
||||||
str[10] = ' ';
|
|
||||||
str[11] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* ! HAVE_DECL_STRMODE */
|
|
||||||
|
|
||||||
/* filemodestring - fill in string STR with an ls-style ASCII
|
|
||||||
representation of the st_mode field of file stats block STATP.
|
|
||||||
12 characters are stored in STR.
|
|
||||||
The characters stored in STR are:
|
|
||||||
|
|
||||||
0 File type, as in ftypelet above, except that other letters are used
|
|
||||||
for files whose type cannot be determined solely from st_mode:
|
|
||||||
|
|
||||||
'F' semaphore
|
|
||||||
'M' migrated file (Cray DMF)
|
|
||||||
'Q' message queue
|
|
||||||
'S' shared memory object
|
|
||||||
'T' typed memory object
|
|
||||||
|
|
||||||
1 'r' if the owner may read, '-' otherwise.
|
|
||||||
|
|
||||||
2 'w' if the owner may write, '-' otherwise.
|
|
||||||
|
|
||||||
3 'x' if the owner may execute, 's' if the file is
|
|
||||||
set-user-id, '-' otherwise.
|
|
||||||
'S' if the file is set-user-id, but the execute
|
|
||||||
bit isn't set.
|
|
||||||
|
|
||||||
4 'r' if group members may read, '-' otherwise.
|
|
||||||
|
|
||||||
5 'w' if group members may write, '-' otherwise.
|
|
||||||
|
|
||||||
6 'x' if group members may execute, 's' if the file is
|
|
||||||
set-group-id, '-' otherwise.
|
|
||||||
'S' if it is set-group-id but not executable.
|
|
||||||
|
|
||||||
7 'r' if any user may read, '-' otherwise.
|
|
||||||
|
|
||||||
8 'w' if any user may write, '-' otherwise.
|
|
||||||
|
|
||||||
9 'x' if any user may execute, 't' if the file is "sticky"
|
|
||||||
(will be retained in swap space after execution), '-'
|
|
||||||
otherwise.
|
|
||||||
'T' if the file is sticky but not executable.
|
|
||||||
|
|
||||||
10 ' ' for compatibility with 4.4BSD strmode,
|
|
||||||
since this interface does not support ACLs.
|
|
||||||
|
|
||||||
11 '\0'. */
|
|
||||||
|
|
||||||
void
|
|
||||||
filemodestring (struct stat const *statp, char *str)
|
|
||||||
{
|
|
||||||
strmode (statp->st_mode, str);
|
|
||||||
|
|
||||||
if (S_TYPEISSEM (statp))
|
|
||||||
str[0] = 'F';
|
|
||||||
else if (IS_MIGRATED_FILE (statp))
|
|
||||||
str[0] = 'M';
|
|
||||||
else if (S_TYPEISMQ (statp))
|
|
||||||
str[0] = 'Q';
|
|
||||||
else if (S_TYPEISSHM (statp))
|
|
||||||
str[0] = 'S';
|
|
||||||
else if (S_TYPEISTMO (statp))
|
|
||||||
str[0] = 'T';
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/* Make a string describing file modes.
|
|
||||||
|
|
||||||
Copyright (C) 1998, 1999, 2003, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef FILEMODE_H_
|
|
||||||
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <sys/stat.h>
|
|
||||||
|
|
||||||
# if HAVE_DECL_STRMODE
|
|
||||||
# include <string.h> /* FreeBSD, OpenBSD */
|
|
||||||
# include <unistd.h> /* NetBSD */
|
|
||||||
# else
|
|
||||||
void strmode (mode_t mode, char *str);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
void filemodestring (struct stat const *statp, char *str);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
/* Concatenate two arbitrary file names.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include "filenamecat.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "dirname.h"
|
|
||||||
#include "xalloc.h"
|
|
||||||
|
|
||||||
#if ! HAVE_MEMPCPY && ! defined mempcpy
|
|
||||||
# define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Return the longest suffix of F that is a relative file name.
|
|
||||||
If it has no such suffix, return the empty string. */
|
|
||||||
|
|
||||||
static char const *
|
|
||||||
longest_relative_suffix (char const *f)
|
|
||||||
{
|
|
||||||
for (f += FILE_SYSTEM_PREFIX_LEN (f); ISSLASH (*f); f++)
|
|
||||||
continue;
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Concatenate two file name components, DIR and ABASE, in
|
|
||||||
newly-allocated storage and return the result.
|
|
||||||
The resulting file name F is such that the commands "ls F" and "(cd
|
|
||||||
DIR; ls BASE)" refer to the same file, where BASE is ABASE with any
|
|
||||||
file system prefixes and leading separators removed.
|
|
||||||
Arrange for a directory separator if necessary between DIR and BASE
|
|
||||||
in the result, removing any redundant separators.
|
|
||||||
In any case, if BASE_IN_RESULT is non-NULL, set
|
|
||||||
*BASE_IN_RESULT to point to the copy of ABASE in the returned
|
|
||||||
concatenation. However, if ABASE begins with more than one slash,
|
|
||||||
set *BASE_IN_RESULT to point to the sole corresponding slash that
|
|
||||||
is copied into the result buffer.
|
|
||||||
|
|
||||||
Return NULL if malloc fails. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
mfile_name_concat (char const *dir, char const *abase, char **base_in_result)
|
|
||||||
{
|
|
||||||
char const *dirbase = last_component (dir);
|
|
||||||
size_t dirbaselen = base_len (dirbase);
|
|
||||||
size_t dirlen = dirbase - dir + dirbaselen;
|
|
||||||
size_t needs_separator = (dirbaselen && ! ISSLASH (dirbase[dirbaselen - 1]));
|
|
||||||
|
|
||||||
char const *base = longest_relative_suffix (abase);
|
|
||||||
size_t baselen = strlen (base);
|
|
||||||
|
|
||||||
char *p_concat = malloc (dirlen + needs_separator + baselen + 1);
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
if (p_concat == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
p = mempcpy (p_concat, dir, dirlen);
|
|
||||||
*p = DIRECTORY_SEPARATOR;
|
|
||||||
p += needs_separator;
|
|
||||||
|
|
||||||
if (base_in_result)
|
|
||||||
*base_in_result = p - IS_ABSOLUTE_FILE_NAME (abase);
|
|
||||||
|
|
||||||
p = mempcpy (p, base, baselen);
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
return p_concat;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Just like mfile_name_concat, above, except, rather than
|
|
||||||
returning NULL upon malloc failure, here, we report the
|
|
||||||
"memory exhausted" condition and exit. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
file_name_concat (char const *dir, char const *abase, char **base_in_result)
|
|
||||||
{
|
|
||||||
char *p = mfile_name_concat (dir, abase, base_in_result);
|
|
||||||
if (p == NULL)
|
|
||||||
xalloc_die ();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/* Concatenate two arbitrary file names.
|
|
||||||
|
|
||||||
Copyright (C) 1996, 1997, 2003, 2005, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
|
||||||
|
|
||||||
char *file_name_concat (char const *dir, char const *base,
|
|
||||||
char **base_in_result);
|
|
||||||
|
|
||||||
char *mfile_name_concat (char const *dir, char const *base,
|
|
||||||
char **base_in_result);
|
|
||||||
@@ -1,354 +0,0 @@
|
|||||||
/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007
|
|
||||||
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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
||||||
|
|
||||||
#ifndef _LIBC
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Enable GNU extensions in fnmatch.h. */
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
# define _GNU_SOURCE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! defined __builtin_expect && __GNUC__ < 3
|
|
||||||
# define __builtin_expect(expr, expected) (expr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fnmatch.h>
|
|
||||||
|
|
||||||
#include <alloca.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define WIDE_CHAR_SUPPORT \
|
|
||||||
(HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \
|
|
||||||
&& HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY))
|
|
||||||
|
|
||||||
/* For platform which support the ISO C amendement 1 functionality we
|
|
||||||
support user defined character classes. */
|
|
||||||
#if defined _LIBC || WIDE_CHAR_SUPPORT
|
|
||||||
# include <wctype.h>
|
|
||||||
# include <wchar.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We need some of the locale data (the collation sequence information)
|
|
||||||
but there is no interface to get this information in general. Therefore
|
|
||||||
we support a correct implementation only in glibc. */
|
|
||||||
#ifdef _LIBC
|
|
||||||
# include "../locale/localeinfo.h"
|
|
||||||
# include "../locale/elem-hash.h"
|
|
||||||
# include "../locale/coll-lookup.h"
|
|
||||||
# include <shlib-compat.h>
|
|
||||||
|
|
||||||
# define CONCAT(a,b) __CONCAT(a,b)
|
|
||||||
# define mbsrtowcs __mbsrtowcs
|
|
||||||
# define fnmatch __fnmatch
|
|
||||||
extern int fnmatch (const char *pattern, const char *string, int flags);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX ((size_t) -1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */
|
|
||||||
#define NO_LEADING_PERIOD(flags) \
|
|
||||||
((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
|
|
||||||
|
|
||||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
|
||||||
actually compiling the library itself, and have not detected a bug
|
|
||||||
in the library. This code is part of the GNU C
|
|
||||||
Library, but also included in many other GNU distributions. Compiling
|
|
||||||
and linking in this code is a waste when using the GNU C library
|
|
||||||
(especially if it is a shared library). Rather than having every GNU
|
|
||||||
program understand `configure --with-gnu-libc' and omit the object files,
|
|
||||||
it is simpler to just do this in the source for each such file. */
|
|
||||||
|
|
||||||
#if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU
|
|
||||||
|
|
||||||
|
|
||||||
# if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
|
|
||||||
# define isblank(c) ((c) == ' ' || (c) == '\t')
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
|
|
||||||
|
|
||||||
# if defined _LIBC || WIDE_CHAR_SUPPORT
|
|
||||||
/* The GNU C library provides support for user-defined character classes
|
|
||||||
and the functions from ISO C amendement 1. */
|
|
||||||
# ifdef CHARCLASS_NAME_MAX
|
|
||||||
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
|
|
||||||
# else
|
|
||||||
/* This shouldn't happen but some implementation might still have this
|
|
||||||
problem. Use a reasonable default value. */
|
|
||||||
# define CHAR_CLASS_MAX_LENGTH 256
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef _LIBC
|
|
||||||
# define IS_CHAR_CLASS(string) __wctype (string)
|
|
||||||
# else
|
|
||||||
# define IS_CHAR_CLASS(string) wctype (string)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef _LIBC
|
|
||||||
# define ISWCTYPE(WC, WT) __iswctype (WC, WT)
|
|
||||||
# else
|
|
||||||
# define ISWCTYPE(WC, WT) iswctype (WC, WT)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
|
|
||||||
/* In this case we are implementing the multibyte character handling. */
|
|
||||||
# define HANDLE_MULTIBYTE 1
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# else
|
|
||||||
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
|
|
||||||
|
|
||||||
# define IS_CHAR_CLASS(string) \
|
|
||||||
(STREQ (string, "alpha") || STREQ (string, "upper") \
|
|
||||||
|| STREQ (string, "lower") || STREQ (string, "digit") \
|
|
||||||
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|
|
||||||
|| STREQ (string, "space") || STREQ (string, "print") \
|
|
||||||
|| STREQ (string, "punct") || STREQ (string, "graph") \
|
|
||||||
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Avoid depending on library functions or files
|
|
||||||
whose names are inconsistent. */
|
|
||||||
|
|
||||||
/* Global variable. */
|
|
||||||
static int posixly_correct;
|
|
||||||
|
|
||||||
# ifndef internal_function
|
|
||||||
/* Inside GNU libc we mark some function in a special way. In other
|
|
||||||
environments simply ignore the marking. */
|
|
||||||
# define internal_function
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Note that this evaluates C many times. */
|
|
||||||
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
|
|
||||||
# define CHAR char
|
|
||||||
# define UCHAR unsigned char
|
|
||||||
# define INT int
|
|
||||||
# define FCT internal_fnmatch
|
|
||||||
# define EXT ext_match
|
|
||||||
# define END end_pattern
|
|
||||||
# define L_(CS) CS
|
|
||||||
# ifdef _LIBC
|
|
||||||
# define BTOWC(C) __btowc (C)
|
|
||||||
# else
|
|
||||||
# define BTOWC(C) btowc (C)
|
|
||||||
# endif
|
|
||||||
# define STRLEN(S) strlen (S)
|
|
||||||
# define STRCAT(D, S) strcat (D, S)
|
|
||||||
# ifdef _LIBC
|
|
||||||
# define MEMPCPY(D, S, N) __mempcpy (D, S, N)
|
|
||||||
# else
|
|
||||||
# if HAVE_MEMPCPY
|
|
||||||
# define MEMPCPY(D, S, N) mempcpy (D, S, N)
|
|
||||||
# else
|
|
||||||
# define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# define MEMCHR(S, C, N) memchr (S, C, N)
|
|
||||||
# define STRCOLL(S1, S2) strcoll (S1, S2)
|
|
||||||
# include "fnmatch_loop.c"
|
|
||||||
|
|
||||||
|
|
||||||
# if HANDLE_MULTIBYTE
|
|
||||||
# define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
|
|
||||||
# define CHAR wchar_t
|
|
||||||
# define UCHAR wint_t
|
|
||||||
# define INT wint_t
|
|
||||||
# define FCT internal_fnwmatch
|
|
||||||
# define EXT ext_wmatch
|
|
||||||
# define END end_wpattern
|
|
||||||
# define L_(CS) L##CS
|
|
||||||
# define BTOWC(C) (C)
|
|
||||||
# ifdef _LIBC
|
|
||||||
# define STRLEN(S) __wcslen (S)
|
|
||||||
# define STRCAT(D, S) __wcscat (D, S)
|
|
||||||
# define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
|
|
||||||
# else
|
|
||||||
# define STRLEN(S) wcslen (S)
|
|
||||||
# define STRCAT(D, S) wcscat (D, S)
|
|
||||||
# if HAVE_WMEMPCPY
|
|
||||||
# define MEMPCPY(D, S, N) wmempcpy (D, S, N)
|
|
||||||
# else
|
|
||||||
# define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N))
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# define MEMCHR(S, C, N) wmemchr (S, C, N)
|
|
||||||
# define STRCOLL(S1, S2) wcscoll (S1, S2)
|
|
||||||
# define WIDE_CHAR_VERSION 1
|
|
||||||
|
|
||||||
# undef IS_CHAR_CLASS
|
|
||||||
/* We have to convert the wide character string in a multibyte string. But
|
|
||||||
we know that the character class names consist of alphanumeric characters
|
|
||||||
from the portable character set, and since the wide character encoding
|
|
||||||
for a member of the portable character set is the same code point as
|
|
||||||
its single-byte encoding, we can use a simplified method to convert the
|
|
||||||
string to a multibyte character string. */
|
|
||||||
static wctype_t
|
|
||||||
is_char_class (const wchar_t *wcs)
|
|
||||||
{
|
|
||||||
char s[CHAR_CLASS_MAX_LENGTH + 1];
|
|
||||||
char *cp = s;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Test for a printable character from the portable character set. */
|
|
||||||
# ifdef _LIBC
|
|
||||||
if (*wcs < 0x20 || *wcs > 0x7e
|
|
||||||
|| *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
|
|
||||||
return (wctype_t) 0;
|
|
||||||
# else
|
|
||||||
switch (*wcs)
|
|
||||||
{
|
|
||||||
case L' ': case L'!': case L'"': case L'#': case L'%':
|
|
||||||
case L'&': case L'\'': case L'(': case L')': case L'*':
|
|
||||||
case L'+': case L',': case L'-': case L'.': case L'/':
|
|
||||||
case L'0': case L'1': case L'2': case L'3': case L'4':
|
|
||||||
case L'5': case L'6': case L'7': case L'8': case L'9':
|
|
||||||
case L':': case L';': case L'<': case L'=': case L'>':
|
|
||||||
case L'?':
|
|
||||||
case L'A': case L'B': case L'C': case L'D': case L'E':
|
|
||||||
case L'F': case L'G': case L'H': case L'I': case L'J':
|
|
||||||
case L'K': case L'L': case L'M': case L'N': case L'O':
|
|
||||||
case L'P': case L'Q': case L'R': case L'S': case L'T':
|
|
||||||
case L'U': case L'V': case L'W': case L'X': case L'Y':
|
|
||||||
case L'Z':
|
|
||||||
case L'[': case L'\\': case L']': case L'^': case L'_':
|
|
||||||
case L'a': case L'b': case L'c': case L'd': case L'e':
|
|
||||||
case L'f': case L'g': case L'h': case L'i': case L'j':
|
|
||||||
case L'k': case L'l': case L'm': case L'n': case L'o':
|
|
||||||
case L'p': case L'q': case L'r': case L's': case L't':
|
|
||||||
case L'u': case L'v': case L'w': case L'x': case L'y':
|
|
||||||
case L'z': case L'{': case L'|': case L'}': case L'~':
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (wctype_t) 0;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Avoid overrunning the buffer. */
|
|
||||||
if (cp == s + CHAR_CLASS_MAX_LENGTH)
|
|
||||||
return (wctype_t) 0;
|
|
||||||
|
|
||||||
*cp++ = (char) *wcs++;
|
|
||||||
}
|
|
||||||
while (*wcs != L'\0');
|
|
||||||
|
|
||||||
*cp = '\0';
|
|
||||||
|
|
||||||
# ifdef _LIBC
|
|
||||||
return __wctype (s);
|
|
||||||
# else
|
|
||||||
return wctype (s);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
# define IS_CHAR_CLASS(string) is_char_class (string)
|
|
||||||
|
|
||||||
# include "fnmatch_loop.c"
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
fnmatch (const char *pattern, const char *string, int flags)
|
|
||||||
{
|
|
||||||
# if HANDLE_MULTIBYTE
|
|
||||||
# define ALLOCA_LIMIT 2000
|
|
||||||
if (__builtin_expect (MB_CUR_MAX, 1) != 1)
|
|
||||||
{
|
|
||||||
mbstate_t ps;
|
|
||||||
size_t patsize;
|
|
||||||
size_t strsize;
|
|
||||||
size_t totsize;
|
|
||||||
wchar_t *wpattern;
|
|
||||||
wchar_t *wstring;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
/* Calculate the size needed to convert the strings to
|
|
||||||
wide characters. */
|
|
||||||
memset (&ps, '\0', sizeof (ps));
|
|
||||||
patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1;
|
|
||||||
if (__builtin_expect (patsize != 0, 1))
|
|
||||||
{
|
|
||||||
assert (mbsinit (&ps));
|
|
||||||
strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1;
|
|
||||||
if (__builtin_expect (strsize != 0, 1))
|
|
||||||
{
|
|
||||||
assert (mbsinit (&ps));
|
|
||||||
totsize = patsize + strsize;
|
|
||||||
if (__builtin_expect (! (patsize <= totsize
|
|
||||||
&& totsize <= SIZE_MAX / sizeof (wchar_t)),
|
|
||||||
0))
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate room for the wide characters. */
|
|
||||||
if (__builtin_expect (totsize < ALLOCA_LIMIT, 1))
|
|
||||||
wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wpattern = malloc (totsize * sizeof (wchar_t));
|
|
||||||
if (__builtin_expect (! wpattern, 0))
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wstring = wpattern + patsize;
|
|
||||||
|
|
||||||
/* Convert the strings into wide characters. */
|
|
||||||
mbsrtowcs (wpattern, &pattern, patsize, &ps);
|
|
||||||
assert (mbsinit (&ps));
|
|
||||||
mbsrtowcs (wstring, &string, strsize, &ps);
|
|
||||||
|
|
||||||
res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1,
|
|
||||||
flags & FNM_PERIOD, flags);
|
|
||||||
|
|
||||||
if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0))
|
|
||||||
free (wpattern);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# endif /* HANDLE_MULTIBYTE */
|
|
||||||
|
|
||||||
return internal_fnmatch (pattern, string, string + strlen (string),
|
|
||||||
flags & FNM_PERIOD, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
# ifdef _LIBC
|
|
||||||
# undef fnmatch
|
|
||||||
versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
|
|
||||||
# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
|
|
||||||
strong_alias (__fnmatch, __fnmatch_old)
|
|
||||||
compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
|
|
||||||
# endif
|
|
||||||
libc_hidden_ver (__fnmatch, fnmatch)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
|
||||||
/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003,
|
|
||||||
2005, 2007 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
||||||
|
|
||||||
#ifndef _FNMATCH_H
|
|
||||||
#define _FNMATCH_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We #undef these before defining them because some losing systems
|
|
||||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
|
||||||
#undef FNM_PATHNAME
|
|
||||||
#undef FNM_NOESCAPE
|
|
||||||
#undef FNM_PERIOD
|
|
||||||
|
|
||||||
/* Bits set in the FLAGS argument to `fnmatch'. */
|
|
||||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
|
||||||
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
|
||||||
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
|
||||||
|
|
||||||
#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
|
|
||||||
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
|
||||||
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
|
||||||
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
|
||||||
# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
|
||||||
#define FNM_NOMATCH 1
|
|
||||||
|
|
||||||
/* This value is returned if the implementation does not support
|
|
||||||
`fnmatch'. Since this is not the case here it will never be
|
|
||||||
returned but the conformance test suites still require the symbol
|
|
||||||
to be defined. */
|
|
||||||
#ifdef _XOPEN_SOURCE
|
|
||||||
# define FNM_NOSYS (-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Match NAME against the file name pattern PATTERN,
|
|
||||||
returning zero if it matches, FNM_NOMATCH if not. */
|
|
||||||
extern int fnmatch (const char *__pattern, const char *__name,
|
|
||||||
int __flags);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* fnmatch.h */
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003,
|
|
||||||
2005, 2007 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
||||||
|
|
||||||
#ifndef _FNMATCH_H
|
|
||||||
#define _FNMATCH_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We #undef these before defining them because some losing systems
|
|
||||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
|
||||||
#undef FNM_PATHNAME
|
|
||||||
#undef FNM_NOESCAPE
|
|
||||||
#undef FNM_PERIOD
|
|
||||||
|
|
||||||
/* Bits set in the FLAGS argument to `fnmatch'. */
|
|
||||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
|
||||||
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
|
||||||
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
|
||||||
|
|
||||||
#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
|
|
||||||
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
|
||||||
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
|
||||||
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
|
||||||
# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
|
||||||
#define FNM_NOMATCH 1
|
|
||||||
|
|
||||||
/* This value is returned if the implementation does not support
|
|
||||||
`fnmatch'. Since this is not the case here it will never be
|
|
||||||
returned but the conformance test suites still require the symbol
|
|
||||||
to be defined. */
|
|
||||||
#ifdef _XOPEN_SOURCE
|
|
||||||
# define FNM_NOSYS (-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Match NAME against the file name pattern PATTERN,
|
|
||||||
returning zero if it matches, FNM_NOMATCH if not. */
|
|
||||||
extern int fnmatch (const char *__pattern, const char *__name,
|
|
||||||
int __flags);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* fnmatch.h */
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,67 +0,0 @@
|
|||||||
/* Invoke fopen, but avoid some glitches.
|
|
||||||
|
|
||||||
Copyright (C) 2001, 2004, 2005, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "stdio-safer.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "unistd-safer.h"
|
|
||||||
|
|
||||||
#ifndef STDERR_FILENO
|
|
||||||
# define STDERR_FILENO 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Like fopen, but do not return stdin, stdout, or stderr. */
|
|
||||||
|
|
||||||
FILE *
|
|
||||||
fopen_safer (char const *file, char const *mode)
|
|
||||||
{
|
|
||||||
FILE *fp = fopen (file, mode);
|
|
||||||
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
int fd = fileno (fp);
|
|
||||||
|
|
||||||
if (0 <= fd && fd <= STDERR_FILENO)
|
|
||||||
{
|
|
||||||
int f = dup_safer (fd);
|
|
||||||
|
|
||||||
if (f < 0)
|
|
||||||
{
|
|
||||||
int e = errno;
|
|
||||||
fclose (fp);
|
|
||||||
errno = e;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fclose (fp) != 0
|
|
||||||
|| ! (fp = fdopen (f, mode)))
|
|
||||||
{
|
|
||||||
int e = errno;
|
|
||||||
close (f);
|
|
||||||
errno = e;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fp;
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/* fpending.c -- return the number of pending output bytes on a stream
|
|
||||||
Copyright (C) 2000, 2004, 2006, 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "fpending.h"
|
|
||||||
|
|
||||||
/* Return the number of pending (aka buffered, unflushed)
|
|
||||||
bytes on the stream, FP, that is open for writing. */
|
|
||||||
size_t
|
|
||||||
__fpending (FILE *fp)
|
|
||||||
{
|
|
||||||
return PENDING_OUTPUT_N_BYTES;
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/* Declare __fpending.
|
|
||||||
|
|
||||||
Copyright (C) 2000, 2003, 2005, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifndef HAVE_DECL___FPENDING
|
|
||||||
"this configure-time declaration test was not run"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_DECL___FPENDING
|
|
||||||
# if HAVE_STDIO_EXT_H
|
|
||||||
# include <stdio_ext.h>
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
size_t __fpending (FILE *);
|
|
||||||
#endif
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
/* Flushing buffers of a FILE stream.
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include "fpurge.h"
|
|
||||||
|
|
||||||
#if HAVE___FPURGE /* glibc >= 2.2, Solaris >= 7 */
|
|
||||||
# include <stdio_ext.h>
|
|
||||||
#endif
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
fpurge (FILE *fp)
|
|
||||||
{
|
|
||||||
#if HAVE___FPURGE /* glibc >= 2.2, Solaris >= 7 */
|
|
||||||
|
|
||||||
__fpurge (fp);
|
|
||||||
/* The __fpurge function does not have a return value. */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, MacOS X */
|
|
||||||
|
|
||||||
/* Call the system's fpurge function. */
|
|
||||||
# undef fpurge
|
|
||||||
# if !HAVE_DECL_FPURGE
|
|
||||||
extern int fpurge (FILE *);
|
|
||||||
# endif
|
|
||||||
int result = fpurge (fp);
|
|
||||||
# if defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
|
|
||||||
if (result == 0)
|
|
||||||
/* Correct the invariants that fpurge broke.
|
|
||||||
<stdio.h> on BSD systems says:
|
|
||||||
"The following always hold: if _flags & __SRD, _w is 0."
|
|
||||||
If this invariant is not fulfilled and the stream is read-write but
|
|
||||||
currently writing, subsequent putc or fputc calls will write directly
|
|
||||||
into the buffer, although they shouldn't be allowed to. */
|
|
||||||
if ((fp->_flags & __SRD) != 0)
|
|
||||||
fp->_w = 0;
|
|
||||||
# endif
|
|
||||||
return result;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Most systems provide FILE as a struct and the necessary bitmask in
|
|
||||||
<stdio.h>, because they need it for implementing getc() and putc() as
|
|
||||||
fast macros. */
|
|
||||||
# if defined _IO_ferror_unlocked /* GNU libc, BeOS */
|
|
||||||
fp->_IO_read_end = fp->_IO_read_ptr;
|
|
||||||
fp->_IO_write_ptr = fp->_IO_write_base;
|
|
||||||
/* Avoid memory leak when there is an active ungetc buffer. */
|
|
||||||
if (fp->_IO_save_base != NULL)
|
|
||||||
{
|
|
||||||
free (fp->_IO_save_base);
|
|
||||||
fp->_IO_save_base = NULL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
# elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
|
|
||||||
fp->_p = fp->_bf._base;
|
|
||||||
fp->_r = 0;
|
|
||||||
fp->_w = ((fp->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */
|
|
||||||
? fp->_bf._size
|
|
||||||
: 0);
|
|
||||||
/* Avoid memory leak when there is an active ungetc buffer. */
|
|
||||||
# if defined __NetBSD__ || defined __OpenBSD__ /* NetBSD, OpenBSD */
|
|
||||||
/* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
|
|
||||||
and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */
|
|
||||||
# define fp_ub ((struct { struct __sbuf _ub; } *) fp->_ext._base)->_ub
|
|
||||||
# else /* FreeBSD, MacOS X, Cygwin */
|
|
||||||
# define fp_ub fp->_ub
|
|
||||||
# endif
|
|
||||||
if (fp_ub._base != NULL)
|
|
||||||
{
|
|
||||||
if (fp_ub._base != fp->_ubuf)
|
|
||||||
free (fp_ub._base);
|
|
||||||
fp_ub._base = NULL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */
|
|
||||||
fp->_ptr = fp->_base;
|
|
||||||
if (fp->_ptr != NULL)
|
|
||||||
fp->_cnt = 0;
|
|
||||||
return 0;
|
|
||||||
# elif defined __UCLIBC__ /* uClibc */
|
|
||||||
# ifdef __STDIO_BUFFERS
|
|
||||||
if (fp->__modeflags & __FLAG_WRITING)
|
|
||||||
fp->__bufpos = fp->__bufstart;
|
|
||||||
else if (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING))
|
|
||||||
fp->__bufpos = fp->__bufread;
|
|
||||||
# endif
|
|
||||||
return 0;
|
|
||||||
# elif defined __QNX__ /* QNX */
|
|
||||||
fp->_Rback = fp->_Back + sizeof (fp->_Back);
|
|
||||||
fp->_Rsave = NULL;
|
|
||||||
if (fp->_Mode & 0x2000 /* _MWRITE */)
|
|
||||||
/* fp->_Buf <= fp->_Next <= fp->_Wend */
|
|
||||||
fp->_Next = fp->_Buf;
|
|
||||||
else
|
|
||||||
/* fp->_Buf <= fp->_Next <= fp->_Rend */
|
|
||||||
fp->_Rend = fp->_Next;
|
|
||||||
return 0;
|
|
||||||
# else
|
|
||||||
#error "Please port gnulib fpurge.c to your platform! Look at the definitions of fflush, setvbuf and ungetc on your system, then report this to bug-gnulib."
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/* Flushing buffers of a FILE stream.
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef _GL_FPURGE_H
|
|
||||||
#define _GL_FPURGE_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Discard all pending buffered I/O on the stream STREAM.
|
|
||||||
STREAM must not be wide-character oriented.
|
|
||||||
Return 0 if successful. Upon error, return -1 and set errno. */
|
|
||||||
#if HAVE_FPURGE
|
|
||||||
# define fpurge rpl_fpurge
|
|
||||||
#endif
|
|
||||||
extern int fpurge (FILE *stream);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _GL_FPURGE_H */
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/* Retrieve information about a FILE stream.
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include "freadahead.h"
|
|
||||||
|
|
||||||
size_t
|
|
||||||
freadahead (FILE *fp)
|
|
||||||
{
|
|
||||||
#if defined _IO_ferror_unlocked /* GNU libc, BeOS */
|
|
||||||
if (fp->_IO_write_ptr > fp->_IO_write_base)
|
|
||||||
return 0;
|
|
||||||
return fp->_IO_read_end - fp->_IO_read_ptr;
|
|
||||||
#elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
|
|
||||||
if ((fp->_flags & __SWR) != 0 || fp->_r < 0)
|
|
||||||
return 0;
|
|
||||||
return fp->_r;
|
|
||||||
#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */
|
|
||||||
# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */
|
|
||||||
# define fp_ ((struct { unsigned char *_ptr; \
|
|
||||||
unsigned char *_base; \
|
|
||||||
unsigned char *_end; \
|
|
||||||
long _cnt; \
|
|
||||||
int _file; \
|
|
||||||
unsigned int _flag; \
|
|
||||||
} *) fp)
|
|
||||||
if ((fp_->_flag & _IOWRT) != 0)
|
|
||||||
return 0;
|
|
||||||
return fp_->_cnt;
|
|
||||||
# else
|
|
||||||
if ((fp->_flag & _IOWRT) != 0)
|
|
||||||
return 0;
|
|
||||||
return fp->_cnt;
|
|
||||||
# endif
|
|
||||||
#elif defined __UCLIBC__ /* uClibc */
|
|
||||||
# ifdef __STDIO_BUFFERS
|
|
||||||
if (fp->__modeflags & __FLAG_WRITING)
|
|
||||||
return 0;
|
|
||||||
return fp->__bufread - fp->__bufpos;
|
|
||||||
# else
|
|
||||||
return 0;
|
|
||||||
# endif
|
|
||||||
#elif defined __QNX__ /* QNX */
|
|
||||||
if ((fp->_Mode & 0x2000 /* _MWRITE */) != 0)
|
|
||||||
return 0;
|
|
||||||
/* fp->_Buf <= fp->_Next <= fp->_Rend */
|
|
||||||
return fp->_Rend - fp->_Next;
|
|
||||||
#else
|
|
||||||
#error "Please port gnulib freadahead.c to your platform! Look at the definition of fflush, fread on your system, then report this to bug-gnulib."
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/* Retrieve information about a FILE stream.
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Assuming the stream STREAM is open for reading:
|
|
||||||
Return the number of bytes waiting in the input buffer of STREAM.
|
|
||||||
|
|
||||||
If this number is 0 and the stream is not currently writing,
|
|
||||||
fflush (STREAM) is known to be a no-op.
|
|
||||||
|
|
||||||
STREAM must not be wide-character oriented. */
|
|
||||||
|
|
||||||
extern size_t freadahead (FILE *stream);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/* Retrieve information about a FILE stream.
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include "freading.h"
|
|
||||||
|
|
||||||
/* Don't use glibc's __freading function in glibc < 2.7, see
|
|
||||||
<http://sourceware.org/bugzilla/show_bug.cgi?id=4359> */
|
|
||||||
#if !(HAVE___FREADING && (!defined __GLIBC__ || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)))
|
|
||||||
|
|
||||||
bool
|
|
||||||
freading (FILE *fp)
|
|
||||||
{
|
|
||||||
/* Most systems provide FILE as a struct and the necessary bitmask in
|
|
||||||
<stdio.h>, because they need it for implementing getc() and putc() as
|
|
||||||
fast macros. */
|
|
||||||
#if defined _IO_ferror_unlocked /* GNU libc, BeOS */
|
|
||||||
return ((fp->_flags & _IO_NO_WRITES) != 0
|
|
||||||
|| ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
|
|
||||||
&& fp->_IO_read_base != NULL));
|
|
||||||
#elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
|
|
||||||
return (fp->_flags & __SRD) != 0;
|
|
||||||
#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */
|
|
||||||
return (fp->_flag & _IOREAD) != 0;
|
|
||||||
#elif defined __UCLIBC__ /* uClibc */
|
|
||||||
return (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) != 0;
|
|
||||||
#elif defined __QNX__ /* QNX */
|
|
||||||
return ((fp->_Mode & 0x2 /* _MOPENW */) == 0
|
|
||||||
|| (fp->_Mode & 0x1000 /* _MREAD */) != 0);
|
|
||||||
#else
|
|
||||||
#error "Please port gnulib freading.c to your platform!"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/* Retrieve information about a FILE stream.
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* Return true if the stream STREAM is opened read-only, or if the
|
|
||||||
last operation on the stream was a read operation. Return false if
|
|
||||||
the stream is opened write-only or append-only, or if it supports
|
|
||||||
writing and there is no current read operation (such as fputc).
|
|
||||||
|
|
||||||
freading and fwriting will never both be true. If STREAM supports
|
|
||||||
both reads and writes, then:
|
|
||||||
- both freading and fwriting might be false when the stream is first
|
|
||||||
opened, after read encounters EOF, or after fflush,
|
|
||||||
- freading might be false or true and fwriting might be false
|
|
||||||
after repositioning (such as fseek, fsetpos, or rewind),
|
|
||||||
depending on the underlying implementation.
|
|
||||||
|
|
||||||
STREAM must not be wide-character oriented. */
|
|
||||||
|
|
||||||
#if HAVE___FREADING && (!defined __GLIBC__ || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
|
|
||||||
/* Solaris >= 7, not glibc >= 2.2, but glibc >= 2.7 */
|
|
||||||
|
|
||||||
# include <stdio_ext.h>
|
|
||||||
# define freading(stream) (__freading (stream) != 0)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
# endif
|
|
||||||
|
|
||||||
extern bool freading (FILE *stream);
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
/* An fseeko() function that, together with fflush(), is POSIX compliant.
|
|
||||||
Copyright (C) 2007 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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* Get off_t and lseek. */
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#undef fseeko
|
|
||||||
#if !HAVE_FSEEKO
|
|
||||||
# undef fseek
|
|
||||||
# define fseeko fseek
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
rpl_fseeko (FILE *fp, off_t offset, int whence)
|
|
||||||
{
|
|
||||||
#if LSEEK_PIPE_BROKEN
|
|
||||||
/* mingw gives bogus answers rather than failure on non-seekable files. */
|
|
||||||
if (lseek (fileno (fp), 0, SEEK_CUR) == -1)
|
|
||||||
return EOF;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* These tests are based on fpurge.c. */
|
|
||||||
#if defined _IO_ferror_unlocked /* GNU libc, BeOS */
|
|
||||||
if (fp->_IO_read_end == fp->_IO_read_ptr
|
|
||||||
&& fp->_IO_write_ptr == fp->_IO_write_base
|
|
||||||
&& fp->_IO_save_base == NULL)
|
|
||||||
#elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
|
|
||||||
# if defined __NetBSD__ || defined __OpenBSD__ /* NetBSD, OpenBSD */
|
|
||||||
/* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
|
|
||||||
and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */
|
|
||||||
# define fp_ub ((struct { struct __sbuf _ub; } *) fp->_ext._base)->_ub
|
|
||||||
# else /* FreeBSD, MacOS X, Cygwin */
|
|
||||||
# define fp_ub fp->_ub
|
|
||||||
# endif
|
|
||||||
# if defined __SL64 && defined __SCLE /* Cygwin */
|
|
||||||
if ((fp->_flags & __SL64) == 0)
|
|
||||||
{
|
|
||||||
/* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit
|
|
||||||
mode; but has an fseeko that requires 64-bit mode. */
|
|
||||||
FILE *tmp = fopen ("/dev/null", "r");
|
|
||||||
if (!tmp)
|
|
||||||
return -1;
|
|
||||||
fp->_flags |= __SL64;
|
|
||||||
fp->_seek64 = tmp->_seek64;
|
|
||||||
fclose (tmp);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
if (fp->_p == fp->_bf._base
|
|
||||||
&& fp->_r == 0
|
|
||||||
&& fp->_w == ((fp->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */
|
|
||||||
? fp->_bf._size
|
|
||||||
: 0)
|
|
||||||
&& fp_ub._base == NULL)
|
|
||||||
#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */
|
|
||||||
# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */
|
|
||||||
# define fp_ ((struct { unsigned char *_ptr; \
|
|
||||||
unsigned char *_base; \
|
|
||||||
unsigned char *_end; \
|
|
||||||
long _cnt; \
|
|
||||||
int _file; \
|
|
||||||
unsigned int _flag; \
|
|
||||||
} *) fp)
|
|
||||||
if (fp_->_ptr == fp_->_base
|
|
||||||
&& (fp_->_ptr == NULL || fp_->_cnt == 0))
|
|
||||||
# else
|
|
||||||
if (fp->_ptr == fp->_base
|
|
||||||
&& (fp->_ptr == NULL || fp->_cnt == 0))
|
|
||||||
# endif
|
|
||||||
#elif defined __UCLIBC__ /* uClibc */
|
|
||||||
if (((fp->__modeflags & __FLAG_WRITING) == 0
|
|
||||||
|| fp->__bufpos == fp->__bufstart)
|
|
||||||
&& ((fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) == 0
|
|
||||||
|| fp->__bufpos == fp->__bufread))
|
|
||||||
#elif defined __QNX__ /* QNX */
|
|
||||||
if ((fp->_Mode & _MWRITE ? fp->_Next == fp->_Buf : fp->_Next == fp->_Rend)
|
|
||||||
&& fp->_Rback == fp->_Back + sizeof (fp->_Back)
|
|
||||||
&& fp->_Rsave == NULL)
|
|
||||||
#else
|
|
||||||
#error "Please port gnulib fseeko.c to your platform! Look at the code in fpurge.c, then report this to bug-gnulib."
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
off_t pos = lseek (fileno (fp), offset, whence);
|
|
||||||
if (pos == -1)
|
|
||||||
{
|
|
||||||
#if defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
|
|
||||||
fp->_flags &= ~__SOFF;
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
|
|
||||||
fp->_offset = pos;
|
|
||||||
fp->_flags |= __SOFF;
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return fseeko (fp, offset, whence);
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/* Work around an fstatat bug on Solaris 9.
|
|
||||||
|
|
||||||
Copyright (C) 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert and Jim Meyering. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#define COMPILING_FSTATAT 1
|
|
||||||
#include "openat.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* fstatat should always follow symbolic links that end in /, but on
|
|
||||||
Solaris 9 it doesn't if AT_SYMLINK_NOFOLLOW is specified. This is
|
|
||||||
the same problem that lstat.c addresses, so solve it in a similar
|
|
||||||
way. */
|
|
||||||
|
|
||||||
int
|
|
||||||
rpl_fstatat (int fd, char const *file, struct stat *st, int flag)
|
|
||||||
{
|
|
||||||
int result = fstatat (fd, file, st, flag);
|
|
||||||
|
|
||||||
if (result == 0 && (flag & AT_SYMLINK_NOFOLLOW) && S_ISLNK (st->st_mode)
|
|
||||||
&& file[strlen (file) - 1] == '/')
|
|
||||||
{
|
|
||||||
/* FILE refers to a symbolic link and the name ends with a slash.
|
|
||||||
Get info about the link's referent. */
|
|
||||||
result = fstatat (fd, file, st, flag & ~AT_SYMLINK_NOFOLLOW);
|
|
||||||
if (result == 0 && ! S_ISDIR (st->st_mode))
|
|
||||||
{
|
|
||||||
/* fstatat succeeded and FILE references a non-directory.
|
|
||||||
But it was specified via a name including a trailing
|
|
||||||
slash. Fail with errno set to ENOTDIR to indicate the
|
|
||||||
contradiction. */
|
|
||||||
errno = ENOTDIR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/* An ftello() function that works around platform bugs.
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* Get lseek. */
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#undef ftello
|
|
||||||
#if !HAVE_FTELLO
|
|
||||||
# undef ftell
|
|
||||||
# define ftello ftell
|
|
||||||
#endif
|
|
||||||
|
|
||||||
off_t
|
|
||||||
rpl_ftello (FILE *fp)
|
|
||||||
{
|
|
||||||
#if LSEEK_PIPE_BROKEN
|
|
||||||
/* mingw gives bogus answers rather than failure on non-seekable files. */
|
|
||||||
if (lseek (fileno (fp), 0, SEEK_CUR) == -1)
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __SL64 && defined __SCLE /* Cygwin */
|
|
||||||
if ((fp->_flags & __SL64) == 0)
|
|
||||||
{
|
|
||||||
/* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit
|
|
||||||
mode; but has an ftello that requires 64-bit mode. */
|
|
||||||
FILE *tmp = fopen ("/dev/null", "r");
|
|
||||||
if (!tmp)
|
|
||||||
return -1;
|
|
||||||
fp->_flags |= __SL64;
|
|
||||||
fp->_seek64 = tmp->_seek64;
|
|
||||||
fclose (tmp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return ftello (fp);
|
|
||||||
}
|
|
||||||
@@ -1,427 +0,0 @@
|
|||||||
/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2004,2005,2006,2007 Free Software
|
|
||||||
Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#if !_LIBC
|
|
||||||
# include <config.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
# include "dirfd.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include <fcntl.h> /* For AT_FDCWD on Solaris 9. */
|
|
||||||
|
|
||||||
#ifndef __set_errno
|
|
||||||
# define __set_errno(val) (errno = (val))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#ifndef _D_EXACT_NAMLEN
|
|
||||||
# define _D_EXACT_NAMLEN(d) strlen ((d)->d_name)
|
|
||||||
#endif
|
|
||||||
#ifndef _D_ALLOC_NAMLEN
|
|
||||||
# define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#if _LIBC
|
|
||||||
# ifndef mempcpy
|
|
||||||
# define mempcpy __mempcpy
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its
|
|
||||||
value exceeds INT_MAX, so its use as an int doesn't conform to the
|
|
||||||
C standard, and GCC and Sun C complain in some cases. */
|
|
||||||
#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553
|
|
||||||
# undef AT_FDCWD
|
|
||||||
# define AT_FDCWD (-3041965)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENAMETOOLONG
|
|
||||||
# define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG)
|
|
||||||
#else
|
|
||||||
# define is_ENAMETOOLONG(x) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MAX
|
|
||||||
# define MAX(a, b) ((a) < (b) ? (b) : (a))
|
|
||||||
#endif
|
|
||||||
#ifndef MIN
|
|
||||||
# define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
# ifdef MAXPATHLEN
|
|
||||||
# define PATH_MAX MAXPATHLEN
|
|
||||||
# else
|
|
||||||
# define PATH_MAX 1024
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if D_INO_IN_DIRENT
|
|
||||||
# define MATCHING_INO(dp, ino) ((dp)->d_ino == (ino))
|
|
||||||
#else
|
|
||||||
# define MATCHING_INO(dp, ino) true
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !_LIBC
|
|
||||||
# define __getcwd rpl_getcwd
|
|
||||||
# define __lstat lstat
|
|
||||||
# define __closedir closedir
|
|
||||||
# define __opendir opendir
|
|
||||||
# define __readdir readdir
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The results of opendir() in this file are not used with dirfd and fchdir,
|
|
||||||
therefore save some unnecessary recursion in fchdir.c. */
|
|
||||||
#undef opendir
|
|
||||||
#undef closedir
|
|
||||||
|
|
||||||
/* Get the name of the current working directory, and put it in SIZE
|
|
||||||
bytes of BUF. Returns NULL if the directory couldn't be determined or
|
|
||||||
SIZE was too small. If successful, returns BUF. In GNU, if BUF is
|
|
||||||
NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
|
|
||||||
unless SIZE == 0, in which case it is as big as necessary. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
__getcwd (char *buf, size_t size)
|
|
||||||
{
|
|
||||||
/* Lengths of big file name components and entire file names, and a
|
|
||||||
deep level of file name nesting. These numbers are not upper
|
|
||||||
bounds; they are merely large values suitable for initial
|
|
||||||
allocations, designed to be large enough for most real-world
|
|
||||||
uses. */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
BIG_FILE_NAME_COMPONENT_LENGTH = 255,
|
|
||||||
BIG_FILE_NAME_LENGTH = MIN (4095, PATH_MAX - 1),
|
|
||||||
DEEP_NESTING = 100
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef AT_FDCWD
|
|
||||||
int fd = AT_FDCWD;
|
|
||||||
bool fd_needs_closing = false;
|
|
||||||
#else
|
|
||||||
char dots[DEEP_NESTING * sizeof ".." + BIG_FILE_NAME_COMPONENT_LENGTH + 1];
|
|
||||||
char *dotlist = dots;
|
|
||||||
size_t dotsize = sizeof dots;
|
|
||||||
size_t dotlen = 0;
|
|
||||||
#endif
|
|
||||||
DIR *dirstream = NULL;
|
|
||||||
dev_t rootdev, thisdev;
|
|
||||||
ino_t rootino, thisino;
|
|
||||||
char *dir;
|
|
||||||
register char *dirp;
|
|
||||||
struct stat st;
|
|
||||||
size_t allocated = size;
|
|
||||||
size_t used;
|
|
||||||
|
|
||||||
#if HAVE_PARTLY_WORKING_GETCWD
|
|
||||||
/* The system getcwd works, except it sometimes fails when it
|
|
||||||
shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT. If
|
|
||||||
AT_FDCWD is not defined, the algorithm below is O(N**2) and this
|
|
||||||
is much slower than the system getcwd (at least on GNU/Linux).
|
|
||||||
So trust the system getcwd's results unless they look
|
|
||||||
suspicious.
|
|
||||||
|
|
||||||
Use the system getcwd even if we have openat support, since the
|
|
||||||
system getcwd works even when a parent is unreadable, while the
|
|
||||||
openat-based approach does not. */
|
|
||||||
|
|
||||||
# undef getcwd
|
|
||||||
dir = getcwd (buf, size);
|
|
||||||
if (dir || (errno != ERANGE && !is_ENAMETOOLONG (errno) && errno != ENOENT))
|
|
||||||
return dir;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
{
|
|
||||||
if (buf != NULL)
|
|
||||||
{
|
|
||||||
__set_errno (EINVAL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
allocated = BIG_FILE_NAME_LENGTH + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf == NULL)
|
|
||||||
{
|
|
||||||
dir = malloc (allocated);
|
|
||||||
if (dir == NULL)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dir = buf;
|
|
||||||
|
|
||||||
dirp = dir + allocated;
|
|
||||||
*--dirp = '\0';
|
|
||||||
|
|
||||||
if (__lstat (".", &st) < 0)
|
|
||||||
goto lose;
|
|
||||||
thisdev = st.st_dev;
|
|
||||||
thisino = st.st_ino;
|
|
||||||
|
|
||||||
if (__lstat ("/", &st) < 0)
|
|
||||||
goto lose;
|
|
||||||
rootdev = st.st_dev;
|
|
||||||
rootino = st.st_ino;
|
|
||||||
|
|
||||||
while (!(thisdev == rootdev && thisino == rootino))
|
|
||||||
{
|
|
||||||
struct dirent *d;
|
|
||||||
dev_t dotdev;
|
|
||||||
ino_t dotino;
|
|
||||||
bool mount_point;
|
|
||||||
int parent_status;
|
|
||||||
size_t dirroom;
|
|
||||||
size_t namlen;
|
|
||||||
bool use_d_ino = true;
|
|
||||||
|
|
||||||
/* Look at the parent directory. */
|
|
||||||
#ifdef AT_FDCWD
|
|
||||||
fd = openat (fd, "..", O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
goto lose;
|
|
||||||
fd_needs_closing = true;
|
|
||||||
parent_status = fstat (fd, &st);
|
|
||||||
#else
|
|
||||||
dotlist[dotlen++] = '.';
|
|
||||||
dotlist[dotlen++] = '.';
|
|
||||||
dotlist[dotlen] = '\0';
|
|
||||||
parent_status = __lstat (dotlist, &st);
|
|
||||||
#endif
|
|
||||||
if (parent_status != 0)
|
|
||||||
goto lose;
|
|
||||||
|
|
||||||
if (dirstream && __closedir (dirstream) != 0)
|
|
||||||
{
|
|
||||||
dirstream = NULL;
|
|
||||||
goto lose;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Figure out if this directory is a mount point. */
|
|
||||||
dotdev = st.st_dev;
|
|
||||||
dotino = st.st_ino;
|
|
||||||
mount_point = dotdev != thisdev;
|
|
||||||
|
|
||||||
/* Search for the last directory. */
|
|
||||||
#ifdef AT_FDCWD
|
|
||||||
dirstream = fdopendir (fd);
|
|
||||||
if (dirstream == NULL)
|
|
||||||
goto lose;
|
|
||||||
/* Reset fd. It may have been closed by fdopendir. */
|
|
||||||
fd = dirfd (dirstream);
|
|
||||||
fd_needs_closing = false;
|
|
||||||
#else
|
|
||||||
dirstream = __opendir (dotlist);
|
|
||||||
if (dirstream == NULL)
|
|
||||||
goto lose;
|
|
||||||
dotlist[dotlen++] = '/';
|
|
||||||
#endif
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
/* Clear errno to distinguish EOF from error if readdir returns
|
|
||||||
NULL. */
|
|
||||||
__set_errno (0);
|
|
||||||
d = __readdir (dirstream);
|
|
||||||
|
|
||||||
/* When we've iterated through all directory entries without finding
|
|
||||||
one with a matching d_ino, rewind the stream and consider each
|
|
||||||
name again, but this time, using lstat. This is necessary in a
|
|
||||||
chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where
|
|
||||||
.., ../.., ../../.., etc. all had the same device number, yet the
|
|
||||||
d_ino values for entries in / did not match those obtained
|
|
||||||
via lstat. */
|
|
||||||
if (d == NULL && errno == 0 && use_d_ino)
|
|
||||||
{
|
|
||||||
use_d_ino = false;
|
|
||||||
rewinddir (dirstream);
|
|
||||||
d = __readdir (dirstream);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d == NULL)
|
|
||||||
{
|
|
||||||
if (errno == 0)
|
|
||||||
/* EOF on dirstream, which can mean e.g., that the current
|
|
||||||
directory has been removed. */
|
|
||||||
__set_errno (ENOENT);
|
|
||||||
goto lose;
|
|
||||||
}
|
|
||||||
if (d->d_name[0] == '.' &&
|
|
||||||
(d->d_name[1] == '\0' ||
|
|
||||||
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (use_d_ino)
|
|
||||||
{
|
|
||||||
bool match = (MATCHING_INO (d, thisino) || mount_point);
|
|
||||||
if (! match)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int entry_status;
|
|
||||||
#ifdef AT_FDCWD
|
|
||||||
entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
|
|
||||||
#else
|
|
||||||
/* Compute size needed for this file name, or for the file
|
|
||||||
name ".." in the same directory, whichever is larger.
|
|
||||||
Room for ".." might be needed the next time through
|
|
||||||
the outer loop. */
|
|
||||||
size_t name_alloc = _D_ALLOC_NAMLEN (d);
|
|
||||||
size_t filesize = dotlen + MAX (sizeof "..", name_alloc);
|
|
||||||
|
|
||||||
if (filesize < dotlen)
|
|
||||||
goto memory_exhausted;
|
|
||||||
|
|
||||||
if (dotsize < filesize)
|
|
||||||
{
|
|
||||||
/* My, what a deep directory tree you have, Grandma. */
|
|
||||||
size_t newsize = MAX (filesize, dotsize * 2);
|
|
||||||
size_t i;
|
|
||||||
if (newsize < dotsize)
|
|
||||||
goto memory_exhausted;
|
|
||||||
if (dotlist != dots)
|
|
||||||
free (dotlist);
|
|
||||||
dotlist = malloc (newsize);
|
|
||||||
if (dotlist == NULL)
|
|
||||||
goto lose;
|
|
||||||
dotsize = newsize;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
dotlist[i++] = '.';
|
|
||||||
dotlist[i++] = '.';
|
|
||||||
dotlist[i++] = '/';
|
|
||||||
}
|
|
||||||
while (i < dotlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d));
|
|
||||||
entry_status = __lstat (dotlist, &st);
|
|
||||||
#endif
|
|
||||||
/* We don't fail here if we cannot stat() a directory entry.
|
|
||||||
This can happen when (network) file systems fail. If this
|
|
||||||
entry is in fact the one we are looking for we will find
|
|
||||||
out soon as we reach the end of the directory without
|
|
||||||
having found anything. */
|
|
||||||
if (entry_status == 0 && S_ISDIR (st.st_mode)
|
|
||||||
&& st.st_dev == thisdev && st.st_ino == thisino)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dirroom = dirp - dir;
|
|
||||||
namlen = _D_EXACT_NAMLEN (d);
|
|
||||||
|
|
||||||
if (dirroom <= namlen)
|
|
||||||
{
|
|
||||||
if (size != 0)
|
|
||||||
{
|
|
||||||
__set_errno (ERANGE);
|
|
||||||
goto lose;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *tmp;
|
|
||||||
size_t oldsize = allocated;
|
|
||||||
|
|
||||||
allocated += MAX (allocated, namlen);
|
|
||||||
if (allocated < oldsize
|
|
||||||
|| ! (tmp = realloc (dir, allocated)))
|
|
||||||
goto memory_exhausted;
|
|
||||||
|
|
||||||
/* Move current contents up to the end of the buffer.
|
|
||||||
This is guaranteed to be non-overlapping. */
|
|
||||||
dirp = memcpy (tmp + allocated - (oldsize - dirroom),
|
|
||||||
tmp + dirroom,
|
|
||||||
oldsize - dirroom);
|
|
||||||
dir = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dirp -= namlen;
|
|
||||||
memcpy (dirp, d->d_name, namlen);
|
|
||||||
*--dirp = '/';
|
|
||||||
|
|
||||||
thisdev = dotdev;
|
|
||||||
thisino = dotino;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dirstream && __closedir (dirstream) != 0)
|
|
||||||
{
|
|
||||||
dirstream = NULL;
|
|
||||||
goto lose;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dirp == &dir[allocated - 1])
|
|
||||||
*--dirp = '/';
|
|
||||||
|
|
||||||
#ifndef AT_FDCWD
|
|
||||||
if (dotlist != dots)
|
|
||||||
free (dotlist);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
used = dir + allocated - dirp;
|
|
||||||
memmove (dir, dirp, used);
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
/* Ensure that the buffer is only as large as necessary. */
|
|
||||||
buf = realloc (dir, used);
|
|
||||||
|
|
||||||
if (buf == NULL)
|
|
||||||
/* Either buf was NULL all along, or `realloc' failed but
|
|
||||||
we still have the original string. */
|
|
||||||
buf = dir;
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
|
|
||||||
memory_exhausted:
|
|
||||||
__set_errno (ENOMEM);
|
|
||||||
lose:
|
|
||||||
{
|
|
||||||
int save = errno;
|
|
||||||
if (dirstream)
|
|
||||||
__closedir (dirstream);
|
|
||||||
#ifdef AT_FDCWD
|
|
||||||
if (fd_needs_closing)
|
|
||||||
close (fd);
|
|
||||||
#else
|
|
||||||
if (dotlist != dots)
|
|
||||||
free (dotlist);
|
|
||||||
#endif
|
|
||||||
if (buf == NULL)
|
|
||||||
free (dir);
|
|
||||||
__set_errno (save);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef weak_alias
|
|
||||||
weak_alias (__getcwd, getcwd)
|
|
||||||
#endif
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
/* getdelim.c --- Implementation of replacement getdelim function.
|
|
||||||
Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007 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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
02110-1301, USA. */
|
|
||||||
|
|
||||||
/* Ported from glibc by Simon Josefsson. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX ((size_t) -1)
|
|
||||||
#endif
|
|
||||||
#ifndef SSIZE_MAX
|
|
||||||
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
|
|
||||||
#endif
|
|
||||||
#if !HAVE_FLOCKFILE
|
|
||||||
# undef flockfile
|
|
||||||
# define flockfile(x) ((void) 0)
|
|
||||||
#endif
|
|
||||||
#if !HAVE_FUNLOCKFILE
|
|
||||||
# undef funlockfile
|
|
||||||
# define funlockfile(x) ((void) 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
|
|
||||||
#ifndef EOVERFLOW
|
|
||||||
# define EOVERFLOW E2BIG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
|
|
||||||
NUL-terminate it). *LINEPTR is a pointer returned from malloc (or
|
|
||||||
NULL), pointing to *N characters of space. It is realloc'ed as
|
|
||||||
necessary. Returns the number of characters read (not including
|
|
||||||
the null terminator), or -1 on error or EOF. */
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
|
|
||||||
{
|
|
||||||
ssize_t result;
|
|
||||||
size_t cur_len = 0;
|
|
||||||
|
|
||||||
if (lineptr == NULL || n == NULL || fp == NULL)
|
|
||||||
{
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
flockfile (fp);
|
|
||||||
|
|
||||||
if (*lineptr == NULL || *n == 0)
|
|
||||||
{
|
|
||||||
*n = 120;
|
|
||||||
*lineptr = (char *) realloc (*lineptr, *n);
|
|
||||||
if (*lineptr == NULL)
|
|
||||||
{
|
|
||||||
result = -1;
|
|
||||||
goto unlock_return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = getc (fp);
|
|
||||||
if (i == EOF)
|
|
||||||
{
|
|
||||||
result = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make enough space for len+1 (for final NUL) bytes. */
|
|
||||||
if (cur_len + 1 >= *n)
|
|
||||||
{
|
|
||||||
size_t needed_max =
|
|
||||||
SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
|
|
||||||
size_t needed = 2 * *n + 1; /* Be generous. */
|
|
||||||
char *new_lineptr;
|
|
||||||
|
|
||||||
if (needed_max < needed)
|
|
||||||
needed = needed_max;
|
|
||||||
if (cur_len + 1 >= needed)
|
|
||||||
{
|
|
||||||
result = -1;
|
|
||||||
errno = EOVERFLOW;
|
|
||||||
goto unlock_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_lineptr = (char *) realloc (*lineptr, needed);
|
|
||||||
if (new_lineptr == NULL)
|
|
||||||
{
|
|
||||||
result = -1;
|
|
||||||
goto unlock_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*lineptr = new_lineptr;
|
|
||||||
*n = needed;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*lineptr)[cur_len] = i;
|
|
||||||
cur_len++;
|
|
||||||
|
|
||||||
if (i == delimiter)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
(*lineptr)[cur_len] = '\0';
|
|
||||||
result = cur_len ? cur_len : result;
|
|
||||||
|
|
||||||
unlock_return:
|
|
||||||
funlockfile (fp); /* doesn't set errno */
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/* getline.c --- Implementation of replacement getline function.
|
|
||||||
Copyright (C) 2005, 2006, 2007 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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
02110-1301, USA. */
|
|
||||||
|
|
||||||
/* Written by Simon Josefsson. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
getline (char **lineptr, size_t *n, FILE *stream)
|
|
||||||
{
|
|
||||||
return getdelim (lineptr, n, '\n', stream);
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,225 +0,0 @@
|
|||||||
/* Declarations for getopt.
|
|
||||||
Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef _GETOPT_H
|
|
||||||
|
|
||||||
#ifndef __need_getopt
|
|
||||||
# define _GETOPT_H 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Standalone applications should #define __GETOPT_PREFIX to an
|
|
||||||
identifier that prefixes the external functions and variables
|
|
||||||
defined in this header. When this happens, include the
|
|
||||||
headers that might declare getopt so that they will not cause
|
|
||||||
confusion if included after this file. Then systematically rename
|
|
||||||
identifiers so that they do not collide with the system functions
|
|
||||||
and variables. Renaming avoids problems with some compilers and
|
|
||||||
linkers. */
|
|
||||||
#if defined __GETOPT_PREFIX && !defined __need_getopt
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <stdio.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
# undef __need_getopt
|
|
||||||
# undef getopt
|
|
||||||
# undef getopt_long
|
|
||||||
# undef getopt_long_only
|
|
||||||
# undef optarg
|
|
||||||
# undef opterr
|
|
||||||
# undef optind
|
|
||||||
# undef optopt
|
|
||||||
# define __GETOPT_CONCAT(x, y) x ## y
|
|
||||||
# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
|
|
||||||
# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
|
|
||||||
# define getopt __GETOPT_ID (getopt)
|
|
||||||
# define getopt_long __GETOPT_ID (getopt_long)
|
|
||||||
# define getopt_long_only __GETOPT_ID (getopt_long_only)
|
|
||||||
# define optarg __GETOPT_ID (optarg)
|
|
||||||
# define opterr __GETOPT_ID (opterr)
|
|
||||||
# define optind __GETOPT_ID (optind)
|
|
||||||
# define optopt __GETOPT_ID (optopt)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Standalone applications get correct prototypes for getopt_long and
|
|
||||||
getopt_long_only; they declare "char **argv". libc uses prototypes
|
|
||||||
with "char *const *argv" that are incorrect because getopt_long and
|
|
||||||
getopt_long_only can permute argv; this is required for backward
|
|
||||||
compatibility (e.g., for LSB 2.0.1).
|
|
||||||
|
|
||||||
This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt',
|
|
||||||
but it caused redefinition warnings if both unistd.h and getopt.h were
|
|
||||||
included, since unistd.h includes getopt.h having previously defined
|
|
||||||
__need_getopt.
|
|
||||||
|
|
||||||
The only place where __getopt_argv_const is used is in definitions
|
|
||||||
of getopt_long and getopt_long_only below, but these are visible
|
|
||||||
only if __need_getopt is not defined, so it is quite safe to rewrite
|
|
||||||
the conditional as follows:
|
|
||||||
*/
|
|
||||||
#if !defined __need_getopt
|
|
||||||
# if defined __GETOPT_PREFIX
|
|
||||||
# define __getopt_argv_const /* empty */
|
|
||||||
# else
|
|
||||||
# define __getopt_argv_const const
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If __GNU_LIBRARY__ is not already defined, either we are being used
|
|
||||||
standalone, or this is the first header included in the source file.
|
|
||||||
If we are being used with glibc, we need to include <features.h>, but
|
|
||||||
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
|
|
||||||
not defined, include <ctype.h>, which will pull in <features.h> for us
|
|
||||||
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
|
|
||||||
doesn't flood the namespace with stuff the way some other headers do.) */
|
|
||||||
#if !defined __GNU_LIBRARY__
|
|
||||||
# include <ctype.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __THROW
|
|
||||||
# ifndef __GNUC_PREREQ
|
|
||||||
# define __GNUC_PREREQ(maj, min) (0)
|
|
||||||
# endif
|
|
||||||
# if defined __cplusplus && __GNUC_PREREQ (2,8)
|
|
||||||
# define __THROW throw ()
|
|
||||||
# else
|
|
||||||
# define __THROW
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* For communication from `getopt' to the caller.
|
|
||||||
When `getopt' finds an option that takes an argument,
|
|
||||||
the argument value is returned here.
|
|
||||||
Also, when `ordering' is RETURN_IN_ORDER,
|
|
||||||
each non-option ARGV-element is returned here. */
|
|
||||||
|
|
||||||
extern char *optarg;
|
|
||||||
|
|
||||||
/* Index in ARGV of the next element to be scanned.
|
|
||||||
This is used for communication to and from the caller
|
|
||||||
and for communication between successive calls to `getopt'.
|
|
||||||
|
|
||||||
On entry to `getopt', zero means this is the first call; initialize.
|
|
||||||
|
|
||||||
When `getopt' returns -1, this is the index of the first of the
|
|
||||||
non-option elements that the caller should itself scan.
|
|
||||||
|
|
||||||
Otherwise, `optind' communicates from one call to the next
|
|
||||||
how much of ARGV has been scanned so far. */
|
|
||||||
|
|
||||||
extern int optind;
|
|
||||||
|
|
||||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
|
||||||
for unrecognized options. */
|
|
||||||
|
|
||||||
extern int opterr;
|
|
||||||
|
|
||||||
/* Set to an option character which was unrecognized. */
|
|
||||||
|
|
||||||
extern int optopt;
|
|
||||||
|
|
||||||
#ifndef __need_getopt
|
|
||||||
/* Describe the long-named options requested by the application.
|
|
||||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
|
||||||
of `struct option' terminated by an element containing a name which is
|
|
||||||
zero.
|
|
||||||
|
|
||||||
The field `has_arg' is:
|
|
||||||
no_argument (or 0) if the option does not take an argument,
|
|
||||||
required_argument (or 1) if the option requires an argument,
|
|
||||||
optional_argument (or 2) if the option takes an optional argument.
|
|
||||||
|
|
||||||
If the field `flag' is not NULL, it points to a variable that is set
|
|
||||||
to the value given in the field `val' when the option is found, but
|
|
||||||
left unchanged if the option is not found.
|
|
||||||
|
|
||||||
To have a long-named option do something other than set an `int' to
|
|
||||||
a compiled-in constant, such as set a value from `optarg', set the
|
|
||||||
option's `flag' field to zero and its `val' field to a nonzero
|
|
||||||
value (the equivalent single-letter option character, if there is
|
|
||||||
one). For long options that have a zero `flag' field, `getopt'
|
|
||||||
returns the contents of the `val' field. */
|
|
||||||
|
|
||||||
struct option
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
/* has_arg can't be an enum because some compilers complain about
|
|
||||||
type mismatches in all the code that assumes it is an int. */
|
|
||||||
int has_arg;
|
|
||||||
int *flag;
|
|
||||||
int val;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
|
||||||
|
|
||||||
# define no_argument 0
|
|
||||||
# define required_argument 1
|
|
||||||
# define optional_argument 2
|
|
||||||
#endif /* need getopt */
|
|
||||||
|
|
||||||
|
|
||||||
/* Get definitions and prototypes for functions to process the
|
|
||||||
arguments in ARGV (ARGC of them, minus the program name) for
|
|
||||||
options given in OPTS.
|
|
||||||
|
|
||||||
Return the option character from OPTS just read. Return -1 when
|
|
||||||
there are no more options. For unrecognized options, or options
|
|
||||||
missing arguments, `optopt' is set to the option letter, and '?' is
|
|
||||||
returned.
|
|
||||||
|
|
||||||
The OPTS string is a list of characters which are recognized option
|
|
||||||
letters, optionally followed by colons, specifying that that letter
|
|
||||||
takes an argument, to be placed in `optarg'.
|
|
||||||
|
|
||||||
If a letter in OPTS is followed by two colons, its argument is
|
|
||||||
optional. This behavior is specific to the GNU `getopt'.
|
|
||||||
|
|
||||||
The argument `--' causes premature termination of argument
|
|
||||||
scanning, explicitly telling `getopt' that there are no more
|
|
||||||
options.
|
|
||||||
|
|
||||||
If OPTS begins with `-', then non-option arguments are treated as
|
|
||||||
arguments to the option '\1'. This behavior is specific to the GNU
|
|
||||||
`getopt'. If OPTS begins with `+', or POSIXLY_CORRECT is set in
|
|
||||||
the environment, then do not permute arguments. */
|
|
||||||
|
|
||||||
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
|
|
||||||
__THROW;
|
|
||||||
|
|
||||||
#ifndef __need_getopt
|
|
||||||
extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
|
|
||||||
const char *__shortopts,
|
|
||||||
const struct option *__longopts, int *__longind)
|
|
||||||
__THROW;
|
|
||||||
extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
|
|
||||||
const char *__shortopts,
|
|
||||||
const struct option *__longopts, int *__longind)
|
|
||||||
__THROW;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Make sure we later can get all the definitions and declarations. */
|
|
||||||
#undef __need_getopt
|
|
||||||
|
|
||||||
#endif /* getopt.h */
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
|
||||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
# include <getopt.h>
|
|
||||||
#else
|
|
||||||
# include <config.h>
|
|
||||||
# include "getopt.h"
|
|
||||||
#endif
|
|
||||||
#include "getopt_int.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* This needs to come after some library #include
|
|
||||||
to get __GNU_LIBRARY__ defined. */
|
|
||||||
#ifdef __GNU_LIBRARY__
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NULL
|
|
||||||
#define NULL 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
|
|
||||||
const struct option *long_options, int *opt_index)
|
|
||||||
{
|
|
||||||
return _getopt_internal (argc, (char **) argv, options, long_options,
|
|
||||||
opt_index, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
_getopt_long_r (int argc, char **argv, const char *options,
|
|
||||||
const struct option *long_options, int *opt_index,
|
|
||||||
struct _getopt_data *d)
|
|
||||||
{
|
|
||||||
return _getopt_internal_r (argc, argv, options, long_options, opt_index,
|
|
||||||
0, 0, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
|
||||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
|
||||||
but does match a short option, it is parsed as a short option
|
|
||||||
instead. */
|
|
||||||
|
|
||||||
int
|
|
||||||
getopt_long_only (int argc, char *__getopt_argv_const *argv,
|
|
||||||
const char *options,
|
|
||||||
const struct option *long_options, int *opt_index)
|
|
||||||
{
|
|
||||||
return _getopt_internal (argc, (char **) argv, options, long_options,
|
|
||||||
opt_index, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
_getopt_long_only_r (int argc, char **argv, const char *options,
|
|
||||||
const struct option *long_options, int *opt_index,
|
|
||||||
struct _getopt_data *d)
|
|
||||||
{
|
|
||||||
return _getopt_internal_r (argc, argv, options, long_options, opt_index,
|
|
||||||
1, 0, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
int digit_optind = 0;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
int this_option_optind = optind ? optind : 1;
|
|
||||||
int option_index = 0;
|
|
||||||
static struct option long_options[] =
|
|
||||||
{
|
|
||||||
{"add", 1, 0, 0},
|
|
||||||
{"append", 0, 0, 0},
|
|
||||||
{"delete", 1, 0, 0},
|
|
||||||
{"verbose", 0, 0, 0},
|
|
||||||
{"create", 0, 0, 0},
|
|
||||||
{"file", 1, 0, 0},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
|
||||||
long_options, &option_index);
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
printf ("option %s", long_options[option_index].name);
|
|
||||||
if (optarg)
|
|
||||||
printf (" with arg %s", optarg);
|
|
||||||
printf ("\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
|
||||||
printf ("digits occur in two different argv-elements.\n");
|
|
||||||
digit_optind = this_option_optind;
|
|
||||||
printf ("option %c\n", c);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'a':
|
|
||||||
printf ("option a\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'b':
|
|
||||||
printf ("option b\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'c':
|
|
||||||
printf ("option c with value `%s'\n", optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd':
|
|
||||||
printf ("option d with value `%s'\n", optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '?':
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind < argc)
|
|
||||||
{
|
|
||||||
printf ("non-option ARGV-elements: ");
|
|
||||||
while (optind < argc)
|
|
||||||
printf ("%s ", argv[optind++]);
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
exit (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TEST */
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
/* Internal declarations for getopt.
|
|
||||||
Copyright (C) 1989-1994,1996-1999,2001,2003,2004
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef _GETOPT_INT_H
|
|
||||||
#define _GETOPT_INT_H 1
|
|
||||||
|
|
||||||
extern int _getopt_internal (int ___argc, char **___argv,
|
|
||||||
const char *__shortopts,
|
|
||||||
const struct option *__longopts, int *__longind,
|
|
||||||
int __long_only, int __posixly_correct);
|
|
||||||
|
|
||||||
|
|
||||||
/* Reentrant versions which can handle parsing multiple argument
|
|
||||||
vectors at the same time. */
|
|
||||||
|
|
||||||
/* Data type for reentrant functions. */
|
|
||||||
struct _getopt_data
|
|
||||||
{
|
|
||||||
/* These have exactly the same meaning as the corresponding global
|
|
||||||
variables, except that they are used for the reentrant
|
|
||||||
versions of getopt. */
|
|
||||||
int optind;
|
|
||||||
int opterr;
|
|
||||||
int optopt;
|
|
||||||
char *optarg;
|
|
||||||
|
|
||||||
/* Internal members. */
|
|
||||||
|
|
||||||
/* True if the internal members have been initialized. */
|
|
||||||
int __initialized;
|
|
||||||
|
|
||||||
/* The next char to be scanned in the option-element
|
|
||||||
in which the last option character we returned was found.
|
|
||||||
This allows us to pick up the scan where we left off.
|
|
||||||
|
|
||||||
If this is zero, or a null string, it means resume the scan
|
|
||||||
by advancing to the next ARGV-element. */
|
|
||||||
char *__nextchar;
|
|
||||||
|
|
||||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
|
||||||
|
|
||||||
If the caller did not specify anything,
|
|
||||||
the default is REQUIRE_ORDER if the environment variable
|
|
||||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
|
||||||
|
|
||||||
REQUIRE_ORDER means don't recognize them as options;
|
|
||||||
stop option processing when the first non-option is seen.
|
|
||||||
This is what Unix does.
|
|
||||||
This mode of operation is selected by either setting the environment
|
|
||||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
|
||||||
of the list of option characters, or by calling getopt.
|
|
||||||
|
|
||||||
PERMUTE is the default. We permute the contents of ARGV as we
|
|
||||||
scan, so that eventually all the non-options are at the end.
|
|
||||||
This allows options to be given in any order, even with programs
|
|
||||||
that were not written to expect this.
|
|
||||||
|
|
||||||
RETURN_IN_ORDER is an option available to programs that were
|
|
||||||
written to expect options and other ARGV-elements in any order
|
|
||||||
and that care about the ordering of the two. We describe each
|
|
||||||
non-option ARGV-element as if it were the argument of an option
|
|
||||||
with character code 1. Using `-' as the first character of the
|
|
||||||
list of option characters selects this mode of operation.
|
|
||||||
|
|
||||||
The special argument `--' forces an end of option-scanning regardless
|
|
||||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
|
||||||
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
|
||||||
} __ordering;
|
|
||||||
|
|
||||||
/* If the POSIXLY_CORRECT environment variable is set
|
|
||||||
or getopt was called. */
|
|
||||||
int __posixly_correct;
|
|
||||||
|
|
||||||
|
|
||||||
/* Handle permutation of arguments. */
|
|
||||||
|
|
||||||
/* Describe the part of ARGV that contains non-options that have
|
|
||||||
been skipped. `first_nonopt' is the index in ARGV of the first
|
|
||||||
of them; `last_nonopt' is the index after the last of them. */
|
|
||||||
|
|
||||||
int __first_nonopt;
|
|
||||||
int __last_nonopt;
|
|
||||||
|
|
||||||
#if defined _LIBC && defined USE_NONOPTION_FLAGS
|
|
||||||
int __nonoption_flags_max_len;
|
|
||||||
int __nonoption_flags_len;
|
|
||||||
# endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The initializer is necessary to set OPTIND and OPTERR to their
|
|
||||||
default values and to clear the initialization flag. */
|
|
||||||
#define _GETOPT_DATA_INITIALIZER { 1, 1 }
|
|
||||||
|
|
||||||
extern int _getopt_internal_r (int ___argc, char **___argv,
|
|
||||||
const char *__shortopts,
|
|
||||||
const struct option *__longopts, int *__longind,
|
|
||||||
int __long_only, int __posixly_correct,
|
|
||||||
struct _getopt_data *__data);
|
|
||||||
|
|
||||||
extern int _getopt_long_r (int ___argc, char **___argv,
|
|
||||||
const char *__shortopts,
|
|
||||||
const struct option *__longopts, int *__longind,
|
|
||||||
struct _getopt_data *__data);
|
|
||||||
|
|
||||||
extern int _getopt_long_only_r (int ___argc, char **___argv,
|
|
||||||
const char *__shortopts,
|
|
||||||
const struct option *__longopts,
|
|
||||||
int *__longind,
|
|
||||||
struct _getopt_data *__data);
|
|
||||||
|
|
||||||
#endif /* getopt_int.h */
|
|
||||||
@@ -1,270 +0,0 @@
|
|||||||
/* Convenience header for conditional use of GNU <libintl.h>.
|
|
||||||
Copyright (C) 1995-1998, 2000-2002, 2004-2006 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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
||||||
|
|
||||||
#ifndef _LIBGETTEXT_H
|
|
||||||
#define _LIBGETTEXT_H 1
|
|
||||||
|
|
||||||
/* NLS can be disabled through the configure --disable-nls option. */
|
|
||||||
#if ENABLE_NLS
|
|
||||||
|
|
||||||
/* Get declarations of GNU message catalog functions. */
|
|
||||||
# include <libintl.h>
|
|
||||||
|
|
||||||
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
|
|
||||||
the gettext() and ngettext() macros. This is an alternative to calling
|
|
||||||
textdomain(), and is useful for libraries. */
|
|
||||||
# ifdef DEFAULT_TEXT_DOMAIN
|
|
||||||
# undef gettext
|
|
||||||
# define gettext(Msgid) \
|
|
||||||
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
|
|
||||||
# undef ngettext
|
|
||||||
# define ngettext(Msgid1, Msgid2, N) \
|
|
||||||
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
|
|
||||||
chokes if dcgettext is defined as a macro. So include it now, to make
|
|
||||||
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
|
|
||||||
as well because people using "gettext.h" will not include <libintl.h>,
|
|
||||||
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
|
|
||||||
is OK. */
|
|
||||||
#if defined(__sun)
|
|
||||||
# include <locale.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
|
|
||||||
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
|
|
||||||
it now, to make later inclusions of <libintl.h> a NOP. */
|
|
||||||
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
|
|
||||||
# include <cstdlib>
|
|
||||||
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
|
|
||||||
# include <libintl.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disabled NLS.
|
|
||||||
The casts to 'const char *' serve the purpose of producing warnings
|
|
||||||
for invalid uses of the value returned from these functions.
|
|
||||||
On pre-ANSI systems without 'const', the config.h file is supposed to
|
|
||||||
contain "#define const". */
|
|
||||||
# define gettext(Msgid) ((const char *) (Msgid))
|
|
||||||
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
|
|
||||||
# define dcgettext(Domainname, Msgid, Category) \
|
|
||||||
((void) (Category), dgettext (Domainname, Msgid))
|
|
||||||
# define ngettext(Msgid1, Msgid2, N) \
|
|
||||||
((N) == 1 \
|
|
||||||
? ((void) (Msgid2), (const char *) (Msgid1)) \
|
|
||||||
: ((void) (Msgid1), (const char *) (Msgid2)))
|
|
||||||
# define dngettext(Domainname, Msgid1, Msgid2, N) \
|
|
||||||
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
|
|
||||||
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
|
|
||||||
((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
|
|
||||||
# define textdomain(Domainname) ((const char *) (Domainname))
|
|
||||||
# define bindtextdomain(Domainname, Dirname) \
|
|
||||||
((void) (Domainname), (const char *) (Dirname))
|
|
||||||
# define bind_textdomain_codeset(Domainname, Codeset) \
|
|
||||||
((void) (Domainname), (const char *) (Codeset))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* A pseudo function call that serves as a marker for the automated
|
|
||||||
extraction of messages, but does not call gettext(). The run-time
|
|
||||||
translation is done at a different place in the code.
|
|
||||||
The argument, String, should be a literal string. Concatenated strings
|
|
||||||
and other string expressions won't work.
|
|
||||||
The macro's expansion is not parenthesized, so that it is suitable as
|
|
||||||
initializer for static 'char[]' or 'const char[]' variables. */
|
|
||||||
#define gettext_noop(String) String
|
|
||||||
|
|
||||||
/* The separator between msgctxt and msgid in a .mo file. */
|
|
||||||
#define GETTEXT_CONTEXT_GLUE "\004"
|
|
||||||
|
|
||||||
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
|
|
||||||
MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
|
|
||||||
short and rarely need to change.
|
|
||||||
The letter 'p' stands for 'particular' or 'special'. */
|
|
||||||
#ifdef DEFAULT_TEXT_DOMAIN
|
|
||||||
# define pgettext(Msgctxt, Msgid) \
|
|
||||||
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
|
|
||||||
#else
|
|
||||||
# define pgettext(Msgctxt, Msgid) \
|
|
||||||
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
|
|
||||||
#endif
|
|
||||||
#define dpgettext(Domainname, Msgctxt, Msgid) \
|
|
||||||
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
|
|
||||||
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
|
|
||||||
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
|
|
||||||
#ifdef DEFAULT_TEXT_DOMAIN
|
|
||||||
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
|
|
||||||
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
|
|
||||||
#else
|
|
||||||
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
|
|
||||||
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
|
|
||||||
#endif
|
|
||||||
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
|
|
||||||
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
|
|
||||||
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
|
|
||||||
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__inline
|
|
||||||
#else
|
|
||||||
#ifdef __cplusplus
|
|
||||||
inline
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
static const char *
|
|
||||||
pgettext_aux (const char *domain,
|
|
||||||
const char *msg_ctxt_id, const char *msgid,
|
|
||||||
int category)
|
|
||||||
{
|
|
||||||
const char *translation = dcgettext (domain, msg_ctxt_id, category);
|
|
||||||
if (translation == msg_ctxt_id)
|
|
||||||
return msgid;
|
|
||||||
else
|
|
||||||
return translation;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__inline
|
|
||||||
#else
|
|
||||||
#ifdef __cplusplus
|
|
||||||
inline
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
static const char *
|
|
||||||
npgettext_aux (const char *domain,
|
|
||||||
const char *msg_ctxt_id, const char *msgid,
|
|
||||||
const char *msgid_plural, unsigned long int n,
|
|
||||||
int category)
|
|
||||||
{
|
|
||||||
const char *translation =
|
|
||||||
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
|
|
||||||
if (translation == msg_ctxt_id || translation == msgid_plural)
|
|
||||||
return (n == 1 ? msgid : msgid_plural);
|
|
||||||
else
|
|
||||||
return translation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
|
|
||||||
can be arbitrary expressions. But for string literals these macros are
|
|
||||||
less efficient than those above. */
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
|
|
||||||
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
|
|
||||||
/* || __STDC_VERSION__ >= 199901L */ )
|
|
||||||
|
|
||||||
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define pgettext_expr(Msgctxt, Msgid) \
|
|
||||||
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
|
|
||||||
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
|
|
||||||
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__inline
|
|
||||||
#else
|
|
||||||
#ifdef __cplusplus
|
|
||||||
inline
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
static const char *
|
|
||||||
dcpgettext_expr (const char *domain,
|
|
||||||
const char *msgctxt, const char *msgid,
|
|
||||||
int category)
|
|
||||||
{
|
|
||||||
size_t msgctxt_len = strlen (msgctxt) + 1;
|
|
||||||
size_t msgid_len = strlen (msgid) + 1;
|
|
||||||
const char *translation;
|
|
||||||
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
|
||||||
char msg_ctxt_id[msgctxt_len + msgid_len];
|
|
||||||
#else
|
|
||||||
char buf[1024];
|
|
||||||
char *msg_ctxt_id =
|
|
||||||
(msgctxt_len + msgid_len <= sizeof (buf)
|
|
||||||
? buf
|
|
||||||
: (char *) malloc (msgctxt_len + msgid_len));
|
|
||||||
if (msg_ctxt_id != NULL)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
|
|
||||||
msg_ctxt_id[msgctxt_len - 1] = '\004';
|
|
||||||
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
|
|
||||||
translation = dcgettext (domain, msg_ctxt_id, category);
|
|
||||||
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
|
||||||
if (msg_ctxt_id != buf)
|
|
||||||
free (msg_ctxt_id);
|
|
||||||
#endif
|
|
||||||
if (translation != msg_ctxt_id)
|
|
||||||
return translation;
|
|
||||||
}
|
|
||||||
return msgid;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
|
|
||||||
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
|
|
||||||
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
|
|
||||||
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__inline
|
|
||||||
#else
|
|
||||||
#ifdef __cplusplus
|
|
||||||
inline
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
static const char *
|
|
||||||
dcnpgettext_expr (const char *domain,
|
|
||||||
const char *msgctxt, const char *msgid,
|
|
||||||
const char *msgid_plural, unsigned long int n,
|
|
||||||
int category)
|
|
||||||
{
|
|
||||||
size_t msgctxt_len = strlen (msgctxt) + 1;
|
|
||||||
size_t msgid_len = strlen (msgid) + 1;
|
|
||||||
const char *translation;
|
|
||||||
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
|
||||||
char msg_ctxt_id[msgctxt_len + msgid_len];
|
|
||||||
#else
|
|
||||||
char buf[1024];
|
|
||||||
char *msg_ctxt_id =
|
|
||||||
(msgctxt_len + msgid_len <= sizeof (buf)
|
|
||||||
? buf
|
|
||||||
: (char *) malloc (msgctxt_len + msgid_len));
|
|
||||||
if (msg_ctxt_id != NULL)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
|
|
||||||
msg_ctxt_id[msgctxt_len - 1] = '\004';
|
|
||||||
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
|
|
||||||
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
|
|
||||||
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
|
||||||
if (msg_ctxt_id != buf)
|
|
||||||
free (msg_ctxt_id);
|
|
||||||
#endif
|
|
||||||
if (!(translation == msg_ctxt_id || translation == msgid_plural))
|
|
||||||
return translation;
|
|
||||||
}
|
|
||||||
return (n == 1 ? msgid : msgid_plural);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _LIBGETTEXT_H */
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/* hash-pjw.c -- compute a hash value from a NUL-terminated string.
|
|
||||||
|
|
||||||
Copyright (C) 2001, 2003, 2006 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "hash-pjw.h"
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
|
|
||||||
|
|
||||||
/* A hash function for NUL-terminated char* strings using
|
|
||||||
the method described by Bruno Haible.
|
|
||||||
See http://www.haible.de/bruno/hashfunc.html. */
|
|
||||||
|
|
||||||
size_t
|
|
||||||
hash_pjw (const void *x, size_t tablesize)
|
|
||||||
{
|
|
||||||
const char *s;
|
|
||||||
size_t h = 0;
|
|
||||||
|
|
||||||
for (s = x; *s; s++)
|
|
||||||
h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
|
|
||||||
|
|
||||||
return h % tablesize;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/* hash-pjw.h -- declaration for a simple hash function
|
|
||||||
Copyright (C) 2001, 2003 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
/* Compute a hash code for a NUL-terminated string starting at X,
|
|
||||||
and return the hash code modulo TABLESIZE.
|
|
||||||
The result is platform dependent: it depends on the size of the 'size_t'
|
|
||||||
type and on the signedness of the 'char' type. */
|
|
||||||
extern size_t hash_pjw (void const *x, size_t tablesize);
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/* Hash functions for file-related triples: name, device, inode.
|
|
||||||
Copyright (C) 2007 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Jim Meyering */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "hash-triple.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "hash-pjw.h"
|
|
||||||
#include "same.h"
|
|
||||||
#include "same-inode.h"
|
|
||||||
|
|
||||||
#define STREQ(a, b) (strcmp ((a), (b)) == 0)
|
|
||||||
|
|
||||||
/* Hash an F_triple, and *do* consider the file name. */
|
|
||||||
size_t
|
|
||||||
triple_hash (void const *x, size_t table_size)
|
|
||||||
{
|
|
||||||
struct F_triple const *p = x;
|
|
||||||
size_t tmp = hash_pjw (p->name, table_size);
|
|
||||||
|
|
||||||
/* Ignoring the device number here should be fine. */
|
|
||||||
return (tmp ^ p->st_ino) % table_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hash an F_triple, without considering the file name. */
|
|
||||||
size_t
|
|
||||||
triple_hash_no_name (void const *x, size_t table_size)
|
|
||||||
{
|
|
||||||
struct F_triple const *p = x;
|
|
||||||
|
|
||||||
/* Ignoring the device number here should be fine. */
|
|
||||||
return p->st_ino % table_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare two F_triple structs. */
|
|
||||||
bool
|
|
||||||
triple_compare (void const *x, void const *y)
|
|
||||||
{
|
|
||||||
struct F_triple const *a = x;
|
|
||||||
struct F_triple const *b = y;
|
|
||||||
return (SAME_INODE (*a, *b) && same_name (a->name, b->name)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
triple_compare_ino_str (void const *x, void const *y)
|
|
||||||
{
|
|
||||||
struct F_triple const *a = x;
|
|
||||||
struct F_triple const *b = y;
|
|
||||||
return (SAME_INODE (*a, *b) && STREQ (a->name, b->name)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free an F_triple. */
|
|
||||||
void
|
|
||||||
triple_free (void *x)
|
|
||||||
{
|
|
||||||
struct F_triple *a = x;
|
|
||||||
free (a->name);
|
|
||||||
free (a);
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user