Remove redundant gnulib files
* cross/lib: Delete. Make configure generate it instead.
This commit is contained in:
parent
3be448f429
commit
f484f6b74f
260 changed files with 0 additions and 72514 deletions
|
@ -1,674 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://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 <https://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
|
||||
<https://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
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
@ -1,50 +0,0 @@
|
|||
/* A C macro for declaring that a function does not return.
|
||||
Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _Noreturn
|
||||
# if (defined __cplusplus \
|
||||
&& ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
|
||||
|| (defined _MSC_VER && 1900 <= _MSC_VER)) \
|
||||
&& 0)
|
||||
/* [[noreturn]] is not practically usable, because with it the syntax
|
||||
extern _Noreturn void func (...);
|
||||
would not be valid; such a declaration would only be valid with 'extern'
|
||||
and '_Noreturn' swapped, or without the 'extern' keyword. However, some
|
||||
AIX system header files and several gnulib header files use precisely
|
||||
this syntax with 'extern'. */
|
||||
# define _Noreturn [[noreturn]]
|
||||
# elif (defined __clang__ && __clang_major__ < 16 \
|
||||
&& defined _GL_WORK_AROUND_LLVM_BUG_59792)
|
||||
/* Compile with -D_GL_WORK_AROUND_LLVM_BUG_59792 to work around
|
||||
that rare LLVM bug, though you may get many false-alarm warnings. */
|
||||
# define _Noreturn
|
||||
# elif ((!defined __cplusplus || defined __clang__) \
|
||||
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
||||
|| (!defined __STRICT_ANSI__ \
|
||||
&& (4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
|
||||
|| (defined __apple_build_version__ \
|
||||
? 6000000 <= __apple_build_version__ \
|
||||
: 3 < __clang_major__ + (5 <= __clang_minor__))))))
|
||||
/* _Noreturn works as-is. */
|
||||
# elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \
|
||||
|| 0x5110 <= __SUNPRO_C)
|
||||
# define _Noreturn __attribute__ ((__noreturn__))
|
||||
# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
|
||||
# define _Noreturn __declspec (noreturn)
|
||||
# else
|
||||
# define _Noreturn
|
||||
# endif
|
||||
#endif
|
|
@ -1,52 +0,0 @@
|
|||
/* Test whether ACLs are well supported on this system.
|
||||
|
||||
Copyright 2013-2023 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <acl.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* Return true if errno value ERRNUM indicates that ACLs are well
|
||||
supported on this system. ERRNUM should be an errno value obtained
|
||||
after an ACL-related system call fails. */
|
||||
bool
|
||||
acl_errno_valid (int errnum)
|
||||
{
|
||||
/* Recognize some common errors such as from an NFS mount that does
|
||||
not support ACLs, even when local drives do. */
|
||||
switch (errnum)
|
||||
{
|
||||
case EBUSY: return false;
|
||||
case EINVAL: return false;
|
||||
#if defined __APPLE__ && defined __MACH__
|
||||
case ENOENT: return false;
|
||||
#endif
|
||||
case ENOSYS: return false;
|
||||
|
||||
#if defined ENOTSUP && ENOTSUP != EOPNOTSUPP
|
||||
# if ENOTSUP != ENOSYS /* Needed for the MS-Windows port of GNU Emacs. */
|
||||
case ENOTSUP: return false;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
case EOPNOTSUPP: return false;
|
||||
default: return true;
|
||||
}
|
||||
}
|
|
@ -1,507 +0,0 @@
|
|||
/* Test whether a file has a nontrivial ACL. -*- coding: utf-8 -*-
|
||||
|
||||
Copyright (C) 2002-2003, 2005-2023 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
#include "acl-internal.h"
|
||||
|
||||
#if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
|
||||
# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
|
||||
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial. */
|
||||
int
|
||||
acl_extended_nontrivial (acl_t acl)
|
||||
{
|
||||
/* acl is non-trivial if it is non-empty. */
|
||||
return (acl_entries (acl) > 0);
|
||||
}
|
||||
|
||||
# else /* Linux, FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
|
||||
Return -1 and set errno upon failure to determine it. */
|
||||
int
|
||||
acl_access_nontrivial (acl_t acl)
|
||||
{
|
||||
/* acl is non-trivial if it has some entries other than for "user::",
|
||||
"group::", and "other::". Normally these three should be present
|
||||
at least, allowing us to write
|
||||
return (3 < acl_entries (acl));
|
||||
but the following code is more robust. */
|
||||
# if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, Cygwin >= 2.5 */
|
||||
|
||||
acl_entry_t ace;
|
||||
int got_one;
|
||||
|
||||
for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
|
||||
got_one > 0;
|
||||
got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
|
||||
{
|
||||
acl_tag_t tag;
|
||||
if (acl_get_tag_type (ace, &tag) < 0)
|
||||
return -1;
|
||||
if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
|
||||
return 1;
|
||||
}
|
||||
return got_one;
|
||||
|
||||
# elif HAVE_ACL_TO_SHORT_TEXT /* IRIX */
|
||||
/* Don't use acl_get_entry: it is undocumented. */
|
||||
|
||||
int count = acl->acl_cnt;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
acl_entry_t ace = &acl->acl_entry[i];
|
||||
acl_tag_t tag = ace->ae_tag;
|
||||
|
||||
if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ
|
||||
|| tag == ACL_OTHER_OBJ))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
# elif HAVE_ACL_FREE_TEXT /* Tru64 */
|
||||
/* Don't use acl_get_entry: it takes only one argument and does not work. */
|
||||
|
||||
int count = acl->acl_num;
|
||||
acl_entry_t ace;
|
||||
|
||||
for (ace = acl->acl_first; count > 0; ace = ace->next, count--)
|
||||
{
|
||||
acl_tag_t tag;
|
||||
acl_perm_t perm;
|
||||
|
||||
tag = ace->entry->acl_type;
|
||||
if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
|
||||
return 1;
|
||||
|
||||
perm = ace->entry->acl_perm;
|
||||
/* On Tru64, perm can also contain non-standard bits such as
|
||||
PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ... */
|
||||
if ((perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)) != 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
# else
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
# endif
|
||||
}
|
||||
|
||||
int
|
||||
acl_default_nontrivial (acl_t acl)
|
||||
{
|
||||
/* acl is non-trivial if it is non-empty. */
|
||||
return (acl_entries (acl) > 0);
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */
|
||||
|
||||
/* Test an ACL retrieved with GETACL.
|
||||
Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nontrivial (int count, aclent_t *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
aclent_t *ace = &entries[i];
|
||||
|
||||
/* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
|
||||
If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
|
||||
We don't need to check ace->a_id in these cases. */
|
||||
if (!(ace->a_type == USER_OBJ
|
||||
|| ace->a_type == GROUP_OBJ
|
||||
|| ace->a_type == OTHER_OBJ
|
||||
/* Note: Cygwin does not return a CLASS_OBJ ("mask:") entry
|
||||
sometimes. */
|
||||
|| ace->a_type == CLASS_OBJ))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# ifdef ACE_GETACL
|
||||
|
||||
/* A shortcut for a bitmask. */
|
||||
# define NEW_ACE_WRITEA_DATA (NEW_ACE_WRITE_DATA | NEW_ACE_APPEND_DATA)
|
||||
|
||||
/* Test an ACL retrieved with ACE_GETACL.
|
||||
Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_ace_nontrivial (int count, ace_t *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* The flags in the ace_t structure changed in a binary incompatible way
|
||||
when ACL_NO_TRIVIAL etc. were introduced in <sys/acl.h> version 1.15.
|
||||
How to distinguish the two conventions at runtime?
|
||||
In the old convention, usually three ACEs have a_flags = ACE_OWNER /
|
||||
ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400. In the new
|
||||
convention, these values are not used. */
|
||||
int old_convention = 0;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
if (entries[i].a_flags & (OLD_ACE_OWNER | OLD_ACE_GROUP | OLD_ACE_OTHER))
|
||||
{
|
||||
old_convention = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (old_convention)
|
||||
/* Running on Solaris 10. */
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
ace_t *ace = &entries[i];
|
||||
|
||||
/* Note:
|
||||
If ace->a_flags = ACE_OWNER, ace->a_who is the st_uid from stat().
|
||||
If ace->a_flags = ACE_GROUP, ace->a_who is the st_gid from stat().
|
||||
We don't need to check ace->a_who in these cases. */
|
||||
if (!(ace->a_type == OLD_ALLOW
|
||||
&& (ace->a_flags == OLD_ACE_OWNER
|
||||
|| ace->a_flags == OLD_ACE_GROUP
|
||||
|| ace->a_flags == OLD_ACE_OTHER)))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Running on Solaris 10 (newer version) or Solaris 11. */
|
||||
unsigned int access_masks[6] =
|
||||
{
|
||||
0, /* owner@ deny */
|
||||
0, /* owner@ allow */
|
||||
0, /* group@ deny */
|
||||
0, /* group@ allow */
|
||||
0, /* everyone@ deny */
|
||||
0 /* everyone@ allow */
|
||||
};
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
ace_t *ace = &entries[i];
|
||||
unsigned int index1;
|
||||
unsigned int index2;
|
||||
|
||||
if (ace->a_type == NEW_ACE_ACCESS_ALLOWED_ACE_TYPE)
|
||||
index1 = 1;
|
||||
else if (ace->a_type == NEW_ACE_ACCESS_DENIED_ACE_TYPE)
|
||||
index1 = 0;
|
||||
else
|
||||
return 1;
|
||||
|
||||
if (ace->a_flags == NEW_ACE_OWNER)
|
||||
index2 = 0;
|
||||
else if (ace->a_flags == (NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP))
|
||||
index2 = 2;
|
||||
else if (ace->a_flags == NEW_ACE_EVERYONE)
|
||||
index2 = 4;
|
||||
else
|
||||
return 1;
|
||||
|
||||
access_masks[index1 + index2] |= ace->a_access_mask;
|
||||
}
|
||||
|
||||
/* The same bit shouldn't be both allowed and denied. */
|
||||
if (access_masks[0] & access_masks[1])
|
||||
return 1;
|
||||
if (access_masks[2] & access_masks[3])
|
||||
return 1;
|
||||
if (access_masks[4] & access_masks[5])
|
||||
return 1;
|
||||
|
||||
/* Check minimum masks. */
|
||||
if ((NEW_ACE_WRITE_NAMED_ATTRS
|
||||
| NEW_ACE_WRITE_ATTRIBUTES
|
||||
| NEW_ACE_WRITE_ACL
|
||||
| NEW_ACE_WRITE_OWNER)
|
||||
& ~ access_masks[1])
|
||||
return 1;
|
||||
access_masks[1] &= ~(NEW_ACE_WRITE_NAMED_ATTRS
|
||||
| NEW_ACE_WRITE_ATTRIBUTES
|
||||
| NEW_ACE_WRITE_ACL
|
||||
| NEW_ACE_WRITE_OWNER);
|
||||
if ((NEW_ACE_READ_NAMED_ATTRS
|
||||
| NEW_ACE_READ_ATTRIBUTES
|
||||
| NEW_ACE_READ_ACL
|
||||
| NEW_ACE_SYNCHRONIZE)
|
||||
& ~ access_masks[5])
|
||||
return 1;
|
||||
access_masks[5] &= ~(NEW_ACE_READ_NAMED_ATTRS
|
||||
| NEW_ACE_READ_ATTRIBUTES
|
||||
| NEW_ACE_READ_ACL
|
||||
| NEW_ACE_SYNCHRONIZE);
|
||||
|
||||
/* Check the allowed or denied bits. */
|
||||
switch ((access_masks[0] | access_masks[1])
|
||||
& ~(NEW_ACE_READ_NAMED_ATTRS
|
||||
| NEW_ACE_READ_ATTRIBUTES
|
||||
| NEW_ACE_READ_ACL
|
||||
| NEW_ACE_SYNCHRONIZE))
|
||||
{
|
||||
case 0:
|
||||
case NEW_ACE_READ_DATA:
|
||||
case NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
switch ((access_masks[2] | access_masks[3])
|
||||
& ~(NEW_ACE_READ_NAMED_ATTRS
|
||||
| NEW_ACE_READ_ATTRIBUTES
|
||||
| NEW_ACE_READ_ACL
|
||||
| NEW_ACE_SYNCHRONIZE))
|
||||
{
|
||||
case 0:
|
||||
case NEW_ACE_READ_DATA:
|
||||
case NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
switch ((access_masks[4] | access_masks[5])
|
||||
& ~(NEW_ACE_WRITE_NAMED_ATTRS
|
||||
| NEW_ACE_WRITE_ATTRIBUTES
|
||||
| NEW_ACE_WRITE_ACL
|
||||
| NEW_ACE_WRITE_OWNER))
|
||||
{
|
||||
case 0:
|
||||
case NEW_ACE_READ_DATA:
|
||||
case NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check that the NEW_ACE_WRITE_DATA and NEW_ACE_APPEND_DATA bits are
|
||||
either both allowed or both denied. */
|
||||
if (((access_masks[0] & NEW_ACE_WRITE_DATA) != 0)
|
||||
!= ((access_masks[0] & NEW_ACE_APPEND_DATA) != 0))
|
||||
return 1;
|
||||
if (((access_masks[2] & NEW_ACE_WRITE_DATA) != 0)
|
||||
!= ((access_masks[2] & NEW_ACE_APPEND_DATA) != 0))
|
||||
return 1;
|
||||
if (((access_masks[4] & NEW_ACE_WRITE_DATA) != 0)
|
||||
!= ((access_masks[4] & NEW_ACE_APPEND_DATA) != 0))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif USE_ACL && HAVE_GETACL /* HP-UX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nontrivial (int count, struct acl_entry *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (count > 3)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct acl_entry *ace = &entries[i];
|
||||
|
||||
if (ace->uid != ACL_NSUSER && ace->gid != ACL_NSGROUP)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# if HAVE_ACLV_H /* HP-UX >= 11.11 */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
aclv_nontrivial (int count, struct acl *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct acl *ace = &entries[i];
|
||||
|
||||
/* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
|
||||
If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
|
||||
We don't need to check ace->a_id in these cases. */
|
||||
if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
|
||||
|| ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
|
||||
|| ace->a_type == CLASS_OBJ
|
||||
|| ace->a_type == OTHER_OBJ))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif USE_ACL && (HAVE_ACLX_GET || HAVE_STATACL) /* AIX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nontrivial (struct acl *a)
|
||||
{
|
||||
/* The normal way to iterate through an ACL is like this:
|
||||
struct acl_entry *ace;
|
||||
for (ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace))
|
||||
{
|
||||
struct ace_id *aei;
|
||||
switch (ace->ace_type)
|
||||
{
|
||||
case ACC_PERMIT:
|
||||
case ACC_DENY:
|
||||
case ACC_SPECIFY:
|
||||
...;
|
||||
}
|
||||
for (aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei))
|
||||
...
|
||||
}
|
||||
*/
|
||||
return (acl_last (a) != a->acl_ext ? 1 : 0);
|
||||
}
|
||||
|
||||
# if HAVE_ACLX_GET && defined ACL_AIX_WIP /* newer AIX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nfs4_nontrivial (nfs4_acl_int_t *a)
|
||||
{
|
||||
# if 1 /* let's try this first */
|
||||
return (a->aclEntryN > 0 ? 1 : 0);
|
||||
# else
|
||||
int count = a->aclEntryN;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
nfs4_ace_int_t *ace = &a->aclEntry[i];
|
||||
|
||||
if (!((ace->flags & ACE4_ID_SPECIAL) != 0
|
||||
&& (ace->aceWho.special_whoid == ACE4_WHO_OWNER
|
||||
|| ace->aceWho.special_whoid == ACE4_WHO_GROUP
|
||||
|| ace->aceWho.special_whoid == ACE4_WHO_EVERYONE)
|
||||
&& ace->aceType == ACE4_ACCESS_ALLOWED_ACE_TYPE
|
||||
&& ace->aceFlags == 0
|
||||
&& (ace->aceMask & ~(ACE4_READ_DATA | ACE4_LIST_DIRECTORY
|
||||
| ACE4_WRITE_DATA | ACE4_ADD_FILE
|
||||
| ACE4_EXECUTE)) == 0))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
# endif
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */
|
||||
|
||||
/* Test an ACL retrieved with ACL_GET.
|
||||
Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nontrivial (int count, struct acl *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct acl *ace = &entries[i];
|
||||
|
||||
/* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
|
||||
If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
|
||||
We don't need to check ace->a_id in these cases. */
|
||||
if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
|
||||
|| ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
|
||||
|| ace->a_type == CLASS_OBJ
|
||||
|| ace->a_type == OTHER_OBJ))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
free_permission_context (struct permission_context *ctx)
|
||||
{
|
||||
#if USE_ACL
|
||||
# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
if (ctx->acl)
|
||||
acl_free (ctx->acl);
|
||||
# if !HAVE_ACL_TYPE_EXTENDED
|
||||
if (ctx->default_acl)
|
||||
acl_free (ctx->default_acl);
|
||||
# endif
|
||||
|
||||
# elif defined GETACL /* Solaris, Cygwin < 2.5 */
|
||||
free (ctx->entries);
|
||||
# ifdef ACE_GETACL
|
||||
free (ctx->ace_entries);
|
||||
# endif
|
||||
|
||||
# elif HAVE_GETACL /* HP-UX */
|
||||
|
||||
# if HAVE_ACLV_H
|
||||
# endif
|
||||
|
||||
# elif HAVE_STATACL /* older AIX */
|
||||
|
||||
# elif HAVE_ACLSORT /* NonStop Kernel */
|
||||
|
||||
# endif
|
||||
#endif
|
||||
}
|
|
@ -1,301 +0,0 @@
|
|||
/* Internal implementation of access control lists. -*- coding: utf-8 -*-
|
||||
|
||||
Copyright (C) 2002-2003, 2005-2023 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* All systems define the ACL related API in <sys/acl.h>. */
|
||||
#if HAVE_SYS_ACL_H
|
||||
# include <sys/acl.h>
|
||||
#endif
|
||||
#if defined HAVE_FACL && ! defined GETACLCNT && defined ACL_CNT
|
||||
# define GETACLCNT ACL_CNT
|
||||
#endif
|
||||
|
||||
/* On Linux and Cygwin >= 2.5, additional ACL related API is available in
|
||||
<acl/libacl.h>. */
|
||||
#ifdef HAVE_ACL_LIBACL_H
|
||||
# include <acl/libacl.h>
|
||||
#endif
|
||||
|
||||
/* On HP-UX >= 11.11, additional ACL API is available in <aclv.h>. */
|
||||
#if HAVE_ACLV_H
|
||||
# include <sys/types.h>
|
||||
# include <aclv.h>
|
||||
/* HP-UX 11.11 lacks these declarations. */
|
||||
extern int acl (char *, int, int, struct acl *);
|
||||
extern int aclsort (int, int, struct acl *);
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <limits.h>
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t) -1)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FCHMOD
|
||||
# define HAVE_FCHMOD false
|
||||
# define fchmod(fd, mode) (-1)
|
||||
#endif
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef ACL_INTERNAL_INLINE
|
||||
# define ACL_INTERNAL_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#if USE_ACL
|
||||
|
||||
# if HAVE_ACL_GET_FILE
|
||||
/* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
|
||||
/* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
|
||||
# ifndef MIN_ACL_ENTRIES
|
||||
# define MIN_ACL_ENTRIES 4
|
||||
# endif
|
||||
|
||||
/* POSIX 1003.1e (draft 17) */
|
||||
# ifdef HAVE_ACL_GET_FD
|
||||
/* Most platforms have a 1-argument acl_get_fd, only OSF/1 has a 2-argument
|
||||
macro(!). */
|
||||
# if HAVE_ACL_FREE_TEXT /* OSF/1 */
|
||||
ACL_INTERNAL_INLINE acl_t
|
||||
rpl_acl_get_fd (int fd)
|
||||
{
|
||||
return acl_get_fd (fd, ACL_TYPE_ACCESS);
|
||||
}
|
||||
# undef acl_get_fd
|
||||
# define acl_get_fd rpl_acl_get_fd
|
||||
# endif
|
||||
# else
|
||||
# define HAVE_ACL_GET_FD false
|
||||
# undef acl_get_fd
|
||||
# define acl_get_fd(fd) (NULL)
|
||||
# endif
|
||||
|
||||
/* POSIX 1003.1e (draft 17) */
|
||||
# ifdef HAVE_ACL_SET_FD
|
||||
/* Most platforms have a 2-argument acl_set_fd, only OSF/1 has a 3-argument
|
||||
macro(!). */
|
||||
# if HAVE_ACL_FREE_TEXT /* OSF/1 */
|
||||
ACL_INTERNAL_INLINE int
|
||||
rpl_acl_set_fd (int fd, acl_t acl)
|
||||
{
|
||||
return acl_set_fd (fd, ACL_TYPE_ACCESS, acl);
|
||||
}
|
||||
# undef acl_set_fd
|
||||
# define acl_set_fd rpl_acl_set_fd
|
||||
# endif
|
||||
# else
|
||||
# define HAVE_ACL_SET_FD false
|
||||
# undef acl_set_fd
|
||||
# define acl_set_fd(fd, acl) (-1)
|
||||
# endif
|
||||
|
||||
/* POSIX 1003.1e (draft 13) */
|
||||
# if ! HAVE_ACL_FREE_TEXT
|
||||
# define acl_free_text(buf) acl_free (buf)
|
||||
# endif
|
||||
|
||||
/* Linux-specific */
|
||||
/* Cygwin >= 2.5 implements this function, but it returns 1 for all
|
||||
directories, thus is unusable. */
|
||||
# if !defined HAVE_ACL_EXTENDED_FILE || defined __CYGWIN__
|
||||
# undef HAVE_ACL_EXTENDED_FILE
|
||||
# define HAVE_ACL_EXTENDED_FILE false
|
||||
# define acl_extended_file(name) (-1)
|
||||
# endif
|
||||
|
||||
# if ! defined HAVE_ACL_FROM_MODE && ! defined HAVE_ACL_FROM_TEXT
|
||||
# define acl_from_mode (NULL)
|
||||
# endif
|
||||
|
||||
/* Set to 0 if a file's mode is stored independently from the ACL. */
|
||||
# if (HAVE_ACL_COPY_EXT_NATIVE && HAVE_ACL_CREATE_ENTRY_NP) || defined __sgi /* Mac OS X, IRIX */
|
||||
# define MODE_INSIDE_ACL 0
|
||||
# endif
|
||||
|
||||
/* Return the number of entries in ACL.
|
||||
Return -1 and set errno upon failure to determine it. */
|
||||
/* Define a replacement for acl_entries if needed. (Only Linux has it.) */
|
||||
# if !HAVE_ACL_ENTRIES
|
||||
# define acl_entries rpl_acl_entries
|
||||
extern int acl_entries (acl_t);
|
||||
# endif
|
||||
|
||||
# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial. */
|
||||
extern int acl_extended_nontrivial (acl_t);
|
||||
# else
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
|
||||
Return -1 and set errno upon failure to determine it. */
|
||||
extern int acl_access_nontrivial (acl_t);
|
||||
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_DEFAULT.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
|
||||
Return -1 and set errno upon failure to determine it. */
|
||||
extern int acl_default_nontrivial (acl_t);
|
||||
# endif
|
||||
|
||||
# elif HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */
|
||||
|
||||
/* Set to 0 if a file's mode is stored independently from the ACL. */
|
||||
# if defined __CYGWIN__ /* Cygwin */
|
||||
# define MODE_INSIDE_ACL 0
|
||||
# endif
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_nontrivial (int count, aclent_t *entries) _GL_ATTRIBUTE_PURE;
|
||||
|
||||
# ifdef ACE_GETACL /* Solaris 10 */
|
||||
|
||||
/* Test an ACL retrieved with ACE_GETACL.
|
||||
Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_ace_nontrivial (int count, ace_t *entries) _GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Definitions for when the built executable is executed on Solaris 10
|
||||
(newer version) or Solaris 11. */
|
||||
/* For a_type. */
|
||||
# define OLD_ALLOW 0
|
||||
# define OLD_DENY 1
|
||||
# define NEW_ACE_ACCESS_ALLOWED_ACE_TYPE 0 /* replaces ALLOW */
|
||||
# define NEW_ACE_ACCESS_DENIED_ACE_TYPE 1 /* replaces DENY */
|
||||
/* For a_flags. */
|
||||
# define OLD_ACE_OWNER 0x0100
|
||||
# define OLD_ACE_GROUP 0x0200
|
||||
# define OLD_ACE_OTHER 0x0400
|
||||
# define NEW_ACE_OWNER 0x1000
|
||||
# define NEW_ACE_GROUP 0x2000
|
||||
# define NEW_ACE_IDENTIFIER_GROUP 0x0040
|
||||
# define NEW_ACE_EVERYONE 0x4000
|
||||
/* For a_access_mask. */
|
||||
# define NEW_ACE_READ_DATA 0x001 /* corresponds to 'r' */
|
||||
# define NEW_ACE_WRITE_DATA 0x002 /* corresponds to 'w' */
|
||||
# define NEW_ACE_APPEND_DATA 0x004
|
||||
# define NEW_ACE_READ_NAMED_ATTRS 0x008
|
||||
# define NEW_ACE_WRITE_NAMED_ATTRS 0x010
|
||||
# define NEW_ACE_EXECUTE 0x020
|
||||
# define NEW_ACE_DELETE_CHILD 0x040
|
||||
# define NEW_ACE_READ_ATTRIBUTES 0x080
|
||||
# define NEW_ACE_WRITE_ATTRIBUTES 0x100
|
||||
# define NEW_ACE_DELETE 0x10000
|
||||
# define NEW_ACE_READ_ACL 0x20000
|
||||
# define NEW_ACE_WRITE_ACL 0x40000
|
||||
# define NEW_ACE_WRITE_OWNER 0x80000
|
||||
# define NEW_ACE_SYNCHRONIZE 0x100000
|
||||
|
||||
# endif
|
||||
|
||||
# elif HAVE_GETACL /* HP-UX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_nontrivial (int count, struct acl_entry *entries);
|
||||
|
||||
# if HAVE_ACLV_H /* HP-UX >= 11.11 */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int aclv_nontrivial (int count, struct acl *entries);
|
||||
|
||||
# endif
|
||||
|
||||
# elif HAVE_ACLX_GET && 0 /* AIX */
|
||||
|
||||
/* TODO */
|
||||
|
||||
# elif HAVE_STATACL /* older AIX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_nontrivial (struct acl *a);
|
||||
|
||||
# elif HAVE_ACLSORT /* NonStop Kernel */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_nontrivial (int count, struct acl *entries);
|
||||
|
||||
# endif
|
||||
|
||||
/* Set to 1 if a file's mode is implicit by the ACL. */
|
||||
# ifndef MODE_INSIDE_ACL
|
||||
# define MODE_INSIDE_ACL 1
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
struct permission_context {
|
||||
mode_t mode;
|
||||
#if USE_ACL
|
||||
# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
acl_t acl;
|
||||
# if !HAVE_ACL_TYPE_EXTENDED
|
||||
acl_t default_acl;
|
||||
# endif
|
||||
bool acls_not_supported;
|
||||
|
||||
# elif defined GETACL /* Solaris, Cygwin < 2.5 */
|
||||
int count;
|
||||
aclent_t *entries;
|
||||
# ifdef ACE_GETACL
|
||||
int ace_count;
|
||||
ace_t *ace_entries;
|
||||
# endif
|
||||
|
||||
# elif HAVE_GETACL /* HP-UX */
|
||||
struct acl_entry entries[NACLENTRIES];
|
||||
int count;
|
||||
# if HAVE_ACLV_H
|
||||
struct acl aclv_entries[NACLVENTRIES];
|
||||
int aclv_count;
|
||||
# endif
|
||||
|
||||
# elif HAVE_STATACL /* older AIX */
|
||||
union { struct acl a; char room[4096]; } u;
|
||||
bool have_u;
|
||||
|
||||
# elif HAVE_ACLSORT /* NonStop Kernel */
|
||||
struct acl entries[NACLENTRIES];
|
||||
int count;
|
||||
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
int get_permissions (const char *, int, mode_t, struct permission_context *);
|
||||
int set_permissions (struct permission_context *, const char *, int);
|
||||
void free_permission_context (struct permission_context *);
|
||||
|
||||
_GL_INLINE_HEADER_END
|
|
@ -1,34 +0,0 @@
|
|||
/* acl.c - access control lists
|
||||
|
||||
Copyright (C) 2002, 2008-2023 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert. */
|
||||
|
||||
#ifndef _GL_ACL_H
|
||||
#define _GL_ACL_H 1
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST;
|
||||
int file_has_acl (char const *, struct stat const *);
|
||||
int qset_acl (char const *, int, mode_t);
|
||||
int set_acl (char const *, int, mode_t);
|
||||
int qcopy_acl (char const *, int, char const *, int, mode_t);
|
||||
int copy_acl (char const *, int, char const *, int, mode_t);
|
||||
int chmod_or_fchmod (char const *, int, mode_t);
|
||||
|
||||
#endif
|
|
@ -1,75 +0,0 @@
|
|||
/* Return the number of entries in an ACL.
|
||||
|
||||
Copyright (C) 2002-2003, 2005-2023 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert and Andreas Gruenbacher. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "acl-internal.h"
|
||||
|
||||
/* This file assumes POSIX-draft like ACLs
|
||||
(Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5). */
|
||||
|
||||
/* Return the number of entries in ACL.
|
||||
Return -1 and set errno upon failure to determine it. */
|
||||
|
||||
int
|
||||
acl_entries (acl_t acl)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (acl != NULL)
|
||||
{
|
||||
#if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, Mac OS X, Cygwin >= 2.5 */
|
||||
# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
|
||||
/* acl_get_entry returns 0 when it successfully fetches an entry,
|
||||
and -1/EINVAL at the end. */
|
||||
acl_entry_t ace;
|
||||
int got_one;
|
||||
|
||||
for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
|
||||
got_one >= 0;
|
||||
got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
|
||||
count++;
|
||||
# else /* Linux, FreeBSD, Cygwin >= 2.5 */
|
||||
/* acl_get_entry returns 1 when it successfully fetches an entry,
|
||||
and 0 at the end. */
|
||||
acl_entry_t ace;
|
||||
int got_one;
|
||||
|
||||
for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
|
||||
got_one > 0;
|
||||
got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
|
||||
count++;
|
||||
if (got_one < 0)
|
||||
return -1;
|
||||
# endif
|
||||
#else /* IRIX, Tru64 */
|
||||
# if HAVE_ACL_TO_SHORT_TEXT /* IRIX */
|
||||
/* Don't use acl_get_entry: it is undocumented. */
|
||||
count = acl->acl_cnt;
|
||||
# endif
|
||||
# if HAVE_ACL_FREE_TEXT /* Tru64 */
|
||||
/* Don't use acl_get_entry: it takes only one argument and does not
|
||||
work. */
|
||||
count = acl->acl_num;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/* af_alg.h - Compute message digests from file streams and buffers.
|
||||
Copyright (C) 2018-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Matteo Croce <mcroce@redhat.com>, 2018.
|
||||
Documentation by Bruno Haible <bruno@clisp.org>, 2018. */
|
||||
|
||||
/* Declare specific functions for computing message digests
|
||||
using the Linux kernel crypto API, if available. This kernel API gives
|
||||
access to specialized crypto instructions (that would also be available
|
||||
in user space) or to crypto devices (not directly available in user space).
|
||||
|
||||
For a more complete set of facilities that use the Linux kernel crypto API,
|
||||
look at libkcapi. */
|
||||
|
||||
#ifndef AF_ALG_H
|
||||
# define AF_ALG_H 1
|
||||
|
||||
# include <stdio.h>
|
||||
# include <errno.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# if USE_LINUX_CRYPTO_API
|
||||
|
||||
/* Compute a message digest of a memory region.
|
||||
|
||||
The memory region starts at BUFFER and is LEN bytes long.
|
||||
|
||||
ALG is the message digest algorithm; see the file /proc/crypto.
|
||||
|
||||
RESBLOCK points to a block of HASHLEN bytes, for the result.
|
||||
HASHLEN must be the length of the message digest, in bytes, in particular:
|
||||
|
||||
alg | hashlen
|
||||
-------+--------
|
||||
md5 | 16
|
||||
sha1 | 20
|
||||
sha224 | 28
|
||||
sha256 | 32
|
||||
sha384 | 48
|
||||
sha512 | 64
|
||||
|
||||
If successful, fill RESBLOCK and return 0.
|
||||
Upon failure, return a negated error number. */
|
||||
int
|
||||
afalg_buffer (const char *buffer, size_t len, const char *alg,
|
||||
void *resblock, ssize_t hashlen);
|
||||
|
||||
/* Compute a message digest of data read from STREAM.
|
||||
|
||||
STREAM is an open file stream. The last operation on STREAM should
|
||||
not be 'ungetc', and if STREAM is also open for writing it should
|
||||
have been fflushed since its last write. Read from the current
|
||||
position to the end of STREAM. Handle regular files efficiently.
|
||||
|
||||
ALG is the message digest algorithm; see the file /proc/crypto.
|
||||
|
||||
RESBLOCK points to a block of HASHLEN bytes, for the result.
|
||||
HASHLEN must be the length of the message digest, in bytes, in particular:
|
||||
|
||||
alg | hashlen
|
||||
-------+--------
|
||||
md5 | 16
|
||||
sha1 | 20
|
||||
sha224 | 28
|
||||
sha256 | 32
|
||||
sha384 | 48
|
||||
sha512 | 64
|
||||
|
||||
If successful, fill RESBLOCK and return 0.
|
||||
Upon failure, return a negated error number.
|
||||
Unless returning 0 or -EIO, restore STREAM's file position so that
|
||||
the caller can fall back on some other method. */
|
||||
int
|
||||
afalg_stream (FILE *stream, const char *alg,
|
||||
void *resblock, ssize_t hashlen);
|
||||
|
||||
# else
|
||||
|
||||
static inline int
|
||||
afalg_buffer (const char *buffer, size_t len, const char *alg,
|
||||
void *resblock, ssize_t hashlen)
|
||||
{
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
static inline int
|
||||
afalg_stream (FILE *stream, const char *alg,
|
||||
void *resblock, ssize_t hashlen)
|
||||
{
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* AF_ALG_H */
|
|
@ -1,72 +0,0 @@
|
|||
/* Memory allocation on the stack.
|
||||
|
||||
Copyright (C) 1995, 1999, 2001-2004, 2006-2023 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* 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
|
||||
/* Some version of mingw have an <alloca.h> that causes trouble when
|
||||
included after 'alloca' gets defined as a macro. As a workaround,
|
||||
include this <alloca.h> first and define 'alloca' as a macro afterwards
|
||||
if needed. */
|
||||
# if defined __GNUC__ && (defined _WIN32 && ! defined __CYGWIN__) && @HAVE_ALLOCA_H@
|
||||
# include_next <alloca.h>
|
||||
# endif
|
||||
#endif
|
||||
#ifndef alloca
|
||||
# if defined __GNUC__ || (__clang_major__ >= 4)
|
||||
# define alloca __builtin_alloca
|
||||
# elif defined _AIX
|
||||
# define alloca __alloca
|
||||
# elif defined _MSC_VER
|
||||
# include <malloc.h>
|
||||
# define alloca _alloca
|
||||
# elif defined __DECC && defined __VMS
|
||||
# define alloca __ALLOCA
|
||||
# elif defined __TANDEM && defined _TNS_E_TARGET
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void *_alloca (unsigned short);
|
||||
# pragma intrinsic (_alloca)
|
||||
# define alloca _alloca
|
||||
# elif defined __MVS__
|
||||
# include <stdlib.h>
|
||||
# else
|
||||
# include <stddef.h>
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void *alloca (size_t);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* _GL_ALLOCA_H */
|
|
@ -1,22 +0,0 @@
|
|||
/* Memory allocators such as malloc+free.
|
||||
|
||||
Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#define _GL_USE_STDLIB_ALLOC 1
|
||||
#include <config.h>
|
||||
#include "allocator.h"
|
||||
#include <stdlib.h>
|
||||
struct allocator const stdlib_allocator = { malloc, realloc, free, NULL };
|
|
@ -1,58 +0,0 @@
|
|||
/* Memory allocators such as malloc+free.
|
||||
|
||||
Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert. */
|
||||
|
||||
#ifndef _GL_ALLOCATOR_H
|
||||
#define _GL_ALLOCATOR_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* An object describing a memory allocator family. */
|
||||
|
||||
struct allocator
|
||||
{
|
||||
/* Do not use GCC attributes such as __attribute__ ((malloc)) with
|
||||
the function types pointed at by these members, because these
|
||||
attributes do not work with pointers to functions. See
|
||||
<https://lists.gnu.org/r/bug-gnulib/2011-04/msg00007.html>. */
|
||||
|
||||
/* Call ALLOCATE to allocate memory, like 'malloc'. On failure ALLOCATE
|
||||
should return NULL, though not necessarily set errno. When given
|
||||
a zero size it may return NULL even if successful. */
|
||||
void *(*allocate) (size_t);
|
||||
|
||||
/* If nonnull, call REALLOCATE to reallocate memory, like 'realloc'.
|
||||
On failure REALLOCATE should return NULL, though not necessarily set
|
||||
errno. When given a zero size it may return NULL even if
|
||||
successful. */
|
||||
void *(*reallocate) (void *, size_t);
|
||||
|
||||
/* Call FREE to free memory, like 'free'. */
|
||||
void (*free) (void *);
|
||||
|
||||
/* If nonnull, call DIE (SIZE) if MALLOC (SIZE) or REALLOC (...,
|
||||
SIZE) fails. DIE should not return. SIZE should equal SIZE_MAX
|
||||
if size_t overflow was detected while calculating sizes to be
|
||||
passed to MALLOC or REALLOC. */
|
||||
void (*die) (size_t);
|
||||
};
|
||||
|
||||
/* An allocator using the stdlib functions and a null DIE function. */
|
||||
extern struct allocator const stdlib_allocator;
|
||||
|
||||
#endif /* _GL_ALLOCATOR_H */
|
|
@ -1,26 +0,0 @@
|
|||
/* A C macro for declaring that specific arguments must not be NULL.
|
||||
Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
|
||||
that the values passed as arguments n, ..., m must be non-NULL pointers.
|
||||
n = 1 stands for the first argument, n = 2 for the second argument etc. */
|
||||
#ifndef _GL_ARG_NONNULL
|
||||
# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__
|
||||
# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
|
||||
# else
|
||||
# define _GL_ARG_NONNULL(params)
|
||||
# endif
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
/* Formatted output to strings.
|
||||
Copyright (C) 1999, 2002, 2006, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "vasnprintf.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
char *
|
||||
asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *result;
|
||||
|
||||
va_start (args, format);
|
||||
result = vasnprintf (resultbuf, lengthp, format, args);
|
||||
va_end (args);
|
||||
return result;
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/* Formatted output to strings.
|
||||
Copyright (C) 1999, 2002, 2006-2007, 2009-2023 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#ifdef IN_LIBASPRINTF
|
||||
# include "vasprintf.h"
|
||||
#else
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
int
|
||||
asprintf (char **resultp, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int result;
|
||||
|
||||
va_start (args, format);
|
||||
result = vasprintf (resultp, format, args);
|
||||
va_end (args);
|
||||
return result;
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/* Substitute for and wrapper around <assert.h>
|
||||
Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Do not guard the include, since <assert.h> is supposed to define
|
||||
the assert macro each time it is included. */
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
#@INCLUDE_NEXT@ @NEXT_ASSERT_H@
|
||||
|
||||
/* The definition of static_assert is copied here. */
|
|
@ -1,146 +0,0 @@
|
|||
/* Define at-style functions like fstatat, unlinkat, fchownat, etc.
|
||||
Copyright (C) 2006, 2009-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Jim Meyering */
|
||||
|
||||
#include "filename.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
|
||||
|
||||
#ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD
|
||||
# include <errno.h>
|
||||
# ifndef ENOTSUP
|
||||
# define ENOTSUP EINVAL
|
||||
# endif
|
||||
#else
|
||||
# include "openat.h"
|
||||
# include "openat-priv.h"
|
||||
# include "save-cwd.h"
|
||||
#endif
|
||||
|
||||
#ifdef AT_FUNC_USE_F1_COND
|
||||
# define CALL_FUNC(F) \
|
||||
(flag == AT_FUNC_USE_F1_COND \
|
||||
? AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS) \
|
||||
: AT_FUNC_F2 (F AT_FUNC_POST_FILE_ARGS))
|
||||
# define VALIDATE_FLAG(F) \
|
||||
if (flag & ~AT_FUNC_USE_F1_COND) \
|
||||
{ \
|
||||
errno = EINVAL; \
|
||||
return FUNC_FAIL; \
|
||||
}
|
||||
#else
|
||||
# define CALL_FUNC(F) (AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS))
|
||||
# define VALIDATE_FLAG(F) /* empty */
|
||||
#endif
|
||||
|
||||
#ifdef AT_FUNC_RESULT
|
||||
# define FUNC_RESULT AT_FUNC_RESULT
|
||||
#else
|
||||
# define FUNC_RESULT int
|
||||
#endif
|
||||
|
||||
#ifdef AT_FUNC_FAIL
|
||||
# define FUNC_FAIL AT_FUNC_FAIL
|
||||
#else
|
||||
# define FUNC_FAIL -1
|
||||
#endif
|
||||
|
||||
/* Call AT_FUNC_F1 to operate on FILE, which is in the directory
|
||||
open on descriptor FD. If AT_FUNC_USE_F1_COND is defined to a value,
|
||||
AT_FUNC_POST_FILE_PARAM_DECLS must include a parameter named flag;
|
||||
call AT_FUNC_F2 if FLAG is 0 or fail if FLAG contains more bits than
|
||||
AT_FUNC_USE_F1_COND. Return int and fail with -1 unless AT_FUNC_RESULT
|
||||
or AT_FUNC_FAIL are defined. 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. */
|
||||
FUNC_RESULT
|
||||
AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS)
|
||||
{
|
||||
VALIDATE_FLAG (flag);
|
||||
|
||||
if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file))
|
||||
return CALL_FUNC (file);
|
||||
|
||||
#ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD
|
||||
errno = ENOTSUP;
|
||||
return FUNC_FAIL;
|
||||
#else
|
||||
{
|
||||
/* Be careful to choose names unlikely to conflict with
|
||||
AT_FUNC_POST_FILE_PARAM_DECLS. */
|
||||
struct saved_cwd saved_cwd;
|
||||
int saved_errno;
|
||||
FUNC_RESULT err;
|
||||
|
||||
{
|
||||
char proc_buf[OPENAT_BUFFER_SIZE];
|
||||
char *proc_file = openat_proc_name (proc_buf, fd, file);
|
||||
if (proc_file)
|
||||
{
|
||||
FUNC_RESULT proc_result = CALL_FUNC (proc_file);
|
||||
int proc_errno = errno;
|
||||
if (proc_file != proc_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 (FUNC_FAIL != 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 (0 <= fd && fd == saved_cwd.desc)
|
||||
{
|
||||
/* If saving the working directory collides with the user's
|
||||
requested fd, then the user's fd must have been closed to
|
||||
begin with. */
|
||||
free_cwd (&saved_cwd);
|
||||
errno = EBADF;
|
||||
return FUNC_FAIL;
|
||||
}
|
||||
|
||||
if (fchdir (fd) != 0)
|
||||
{
|
||||
saved_errno = errno;
|
||||
free_cwd (&saved_cwd);
|
||||
errno = saved_errno;
|
||||
return FUNC_FAIL;
|
||||
}
|
||||
|
||||
err = CALL_FUNC (file);
|
||||
saved_errno = (err == FUNC_FAIL ? errno : 0);
|
||||
|
||||
if (restore_cwd (&saved_cwd) != 0)
|
||||
openat_restore_fail (errno);
|
||||
|
||||
free_cwd (&saved_cwd);
|
||||
|
||||
if (saved_errno)
|
||||
errno = saved_errno;
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#undef CALL_FUNC
|
||||
#undef FUNC_RESULT
|
||||
#undef FUNC_FAIL
|
|
@ -1,226 +0,0 @@
|
|||
/* ATTRIBUTE_* macros for using attributes in GCC and similar compilers
|
||||
|
||||
Copyright 2020-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert. */
|
||||
|
||||
/* Provide public ATTRIBUTE_* names for the private _GL_ATTRIBUTE_*
|
||||
macros used within Gnulib. */
|
||||
|
||||
/* These attributes can be placed in two ways:
|
||||
- At the start of a declaration (i.e. even before storage-class
|
||||
specifiers!); then they apply to all entities that are declared
|
||||
by the declaration.
|
||||
- Immediately after the name of an entity being declared by the
|
||||
declaration; then they apply to that entity only. */
|
||||
|
||||
#ifndef _GL_ATTRIBUTE_H
|
||||
#define _GL_ATTRIBUTE_H
|
||||
|
||||
|
||||
/* This file defines two types of attributes:
|
||||
* C23 standard attributes. These have macro names that do not begin with
|
||||
'ATTRIBUTE_'.
|
||||
* Selected GCC attributes; see:
|
||||
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
|
||||
https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
|
||||
https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html
|
||||
These names begin with 'ATTRIBUTE_' to avoid name clashes. */
|
||||
|
||||
|
||||
/* =============== Attributes for specific kinds of functions =============== */
|
||||
|
||||
/* Attributes for functions that should not be used. */
|
||||
|
||||
/* Warn if the entity is used. */
|
||||
/* Applies to:
|
||||
- function, variable,
|
||||
- struct, union, struct/union member,
|
||||
- enumeration, enumeration item,
|
||||
- typedef,
|
||||
in C++ also: namespace, class, template specialization. */
|
||||
#define DEPRECATED _GL_ATTRIBUTE_DEPRECATED
|
||||
|
||||
/* If a function call is not optimized way, warn with MSG. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_WARNING(msg) _GL_ATTRIBUTE_WARNING (msg)
|
||||
|
||||
/* If a function call is not optimized way, report an error with MSG. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_ERROR(msg) _GL_ATTRIBUTE_ERROR (msg)
|
||||
|
||||
|
||||
/* Attributes for memory-allocating functions. */
|
||||
|
||||
/* The function returns a pointer to freshly allocated memory. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_MALLOC _GL_ATTRIBUTE_MALLOC
|
||||
|
||||
/* ATTRIBUTE_ALLOC_SIZE ((N)) - The Nth argument of the function
|
||||
is the size of the returned memory block.
|
||||
ATTRIBUTE_ALLOC_SIZE ((M, N)) - Multiply the Mth and Nth arguments
|
||||
to determine the size of the returned memory block. */
|
||||
/* Applies to: function, pointer to function, function types. */
|
||||
#define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args)
|
||||
|
||||
/* ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
|
||||
that can be freed by passing them as the Ith argument to the
|
||||
function F.
|
||||
ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
|
||||
can be freed via 'free'; it can be used only after declaring 'free'. */
|
||||
/* Applies to: functions. Cannot be used on inline functions. */
|
||||
#define ATTRIBUTE_DEALLOC(f, i) _GL_ATTRIBUTE_DEALLOC(f, i)
|
||||
#define ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC_FREE
|
||||
|
||||
/* Attributes for variadic functions. */
|
||||
|
||||
/* The variadic function expects a trailing NULL argument.
|
||||
ATTRIBUTE_SENTINEL () - The last argument is NULL (requires C99).
|
||||
ATTRIBUTE_SENTINEL ((N)) - The (N+1)st argument from the end is NULL. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_SENTINEL(pos) _GL_ATTRIBUTE_SENTINEL (pos)
|
||||
|
||||
|
||||
/* ================== Attributes for compiler diagnostics ================== */
|
||||
|
||||
/* Attributes that help the compiler diagnose programmer mistakes.
|
||||
Some of them may also help for some compiler optimizations. */
|
||||
|
||||
/* ATTRIBUTE_FORMAT ((ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)) -
|
||||
The STRING-INDEXth function argument is a format string of style
|
||||
ARCHETYPE, which is one of:
|
||||
printf, gnu_printf
|
||||
scanf, gnu_scanf,
|
||||
strftime, gnu_strftime,
|
||||
strfmon,
|
||||
or the same thing prefixed and suffixed with '__'.
|
||||
If FIRST-TO-CHECK is not 0, arguments starting at FIRST-TO_CHECK
|
||||
are suitable for the format string. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_FORMAT(spec) _GL_ATTRIBUTE_FORMAT (spec)
|
||||
|
||||
/* ATTRIBUTE_NONNULL ((N1, N2,...)) - Arguments N1, N2,... must not be NULL.
|
||||
ATTRIBUTE_NONNULL () - All pointer arguments must not be null. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL (args)
|
||||
|
||||
/* The function's return value is a non-NULL pointer. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_RETURNS_NONNULL _GL_ATTRIBUTE_RETURNS_NONNULL
|
||||
|
||||
/* Warn if the caller does not use the return value,
|
||||
unless the caller uses something like ignore_value. */
|
||||
/* Applies to: function, enumeration, class. */
|
||||
#define NODISCARD _GL_ATTRIBUTE_NODISCARD
|
||||
|
||||
|
||||
/* Attributes that disable false alarms when the compiler diagnoses
|
||||
programmer "mistakes". */
|
||||
|
||||
/* Do not warn if the entity is not used. */
|
||||
/* Applies to:
|
||||
- function, variable,
|
||||
- struct, union, struct/union member,
|
||||
- enumeration, enumeration item,
|
||||
- typedef,
|
||||
in C++ also: class. */
|
||||
#define MAYBE_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED
|
||||
|
||||
/* The contents of a character array is not meant to be NUL-terminated. */
|
||||
/* Applies to: struct/union members and variables that are arrays of element
|
||||
type '[[un]signed] char'. */
|
||||
#define ATTRIBUTE_NONSTRING _GL_ATTRIBUTE_NONSTRING
|
||||
|
||||
/* Do not warn if control flow falls through to the immediately
|
||||
following 'case' or 'default' label. */
|
||||
/* Applies to: Empty statement (;), inside a 'switch' statement. */
|
||||
#define FALLTHROUGH _GL_ATTRIBUTE_FALLTHROUGH
|
||||
|
||||
|
||||
/* ================== Attributes for debugging information ================== */
|
||||
|
||||
/* Attributes regarding debugging information emitted by the compiler. */
|
||||
|
||||
/* Omit the function from stack traces when debugging. */
|
||||
/* Applies to: function. */
|
||||
#define ATTRIBUTE_ARTIFICIAL _GL_ATTRIBUTE_ARTIFICIAL
|
||||
|
||||
/* Make the entity visible to debuggers etc., even with '-fwhole-program'. */
|
||||
/* Applies to: functions, variables. */
|
||||
#define ATTRIBUTE_EXTERNALLY_VISIBLE _GL_ATTRIBUTE_EXTERNALLY_VISIBLE
|
||||
|
||||
|
||||
/* ========== Attributes that mainly direct compiler optimizations ========== */
|
||||
|
||||
/* The function does not throw exceptions. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_NOTHROW _GL_ATTRIBUTE_NOTHROW
|
||||
|
||||
/* Do not inline the function. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_NOINLINE _GL_ATTRIBUTE_NOINLINE
|
||||
|
||||
/* Always inline the function, and report an error if the compiler
|
||||
cannot inline. */
|
||||
/* Applies to: function. */
|
||||
#define ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE
|
||||
|
||||
/* It is OK for a compiler to omit duplicate calls with the same arguments.
|
||||
This attribute is safe for a function that neither depends on
|
||||
nor affects observable state, and always returns exactly once -
|
||||
e.g., does not loop forever, and does not call longjmp.
|
||||
(This attribute is stricter than ATTRIBUTE_PURE.) */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST
|
||||
|
||||
/* It is OK for a compiler to omit duplicate calls with the same
|
||||
arguments if observable state is not changed between calls.
|
||||
This attribute is safe for a function that does not affect
|
||||
observable state, and always returns exactly once.
|
||||
(This attribute is looser than ATTRIBUTE_CONST.) */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE
|
||||
|
||||
/* The function is rarely executed. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_COLD _GL_ATTRIBUTE_COLD
|
||||
|
||||
/* If called from some other compilation unit, the function executes
|
||||
code from that unit only by return or by exception handling,
|
||||
letting the compiler optimize that unit more aggressively. */
|
||||
/* Applies to: functions. */
|
||||
#define ATTRIBUTE_LEAF _GL_ATTRIBUTE_LEAF
|
||||
|
||||
/* For struct members: The member has the smallest possible alignment.
|
||||
For struct, union, class: All members have the smallest possible alignment,
|
||||
minimizing the memory required. */
|
||||
/* Applies to: struct members, struct, union,
|
||||
in C++ also: class. */
|
||||
#define ATTRIBUTE_PACKED _GL_ATTRIBUTE_PACKED
|
||||
|
||||
|
||||
/* ================ Attributes that make invalid code valid ================ */
|
||||
|
||||
/* Attributes that prevent fatal compiler optimizations for code that is not
|
||||
fully ISO C compliant. */
|
||||
|
||||
/* Pointers to the type may point to the same storage as pointers to
|
||||
other types, thus disabling strict aliasing optimization. */
|
||||
/* Applies to: types. */
|
||||
#define ATTRIBUTE_MAY_ALIAS _GL_ATTRIBUTE_MAY_ALIAS
|
||||
|
||||
|
||||
#endif /* _GL_ATTRIBUTE_H */
|
|
@ -1,39 +0,0 @@
|
|||
/* Binary mode I/O.
|
||||
Copyright 2017-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define BINARY_IO_INLINE _GL_EXTERN_INLINE
|
||||
#include "binary-io.h"
|
||||
|
||||
#if defined __DJGPP__ || defined __EMX__
|
||||
# include <unistd.h>
|
||||
|
||||
int
|
||||
set_binary_mode (int fd, int mode)
|
||||
{
|
||||
if (isatty (fd))
|
||||
/* If FD refers to a console (not a pipe, not a regular file),
|
||||
O_TEXT is the only reasonable mode, both on input and on output.
|
||||
Silently ignore the request. If we were to return -1 here,
|
||||
all programs that use xset_binary_mode would fail when run
|
||||
with console input or console output. */
|
||||
return O_TEXT;
|
||||
else
|
||||
return __gl_setmode (fd, mode);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,77 +0,0 @@
|
|||
/* Binary mode I/O.
|
||||
Copyright (C) 2001, 2003, 2005, 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _BINARY_H
|
||||
#define _BINARY_H
|
||||
|
||||
/* For systems that distinguish between text and binary I/O.
|
||||
O_BINARY is guaranteed by the gnulib <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>
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef BINARY_IO_INLINE
|
||||
# define BINARY_IO_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#if O_BINARY
|
||||
# if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__
|
||||
# include <io.h> /* declares setmode() */
|
||||
# define __gl_setmode setmode
|
||||
# else
|
||||
# define __gl_setmode _setmode
|
||||
# undef fileno
|
||||
# define fileno _fileno
|
||||
# endif
|
||||
#else
|
||||
/* On reasonable systems, binary I/O is the only choice. */
|
||||
/* Use a function rather than a macro, to avoid gcc warnings
|
||||
"warning: statement with no effect". */
|
||||
BINARY_IO_INLINE int
|
||||
__gl_setmode (_GL_UNUSED int fd, _GL_UNUSED int mode)
|
||||
{
|
||||
return O_BINARY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set FD's mode to MODE, which should be either O_TEXT or O_BINARY.
|
||||
Return the old mode if successful, -1 (setting errno) on failure.
|
||||
Ordinarily this function would be called 'setmode', since that is
|
||||
its old name on MS-Windows, but it is called 'set_binary_mode' here
|
||||
to avoid colliding with a BSD function of another name. */
|
||||
|
||||
#if defined __DJGPP__ || defined __EMX__
|
||||
extern int set_binary_mode (int fd, int mode);
|
||||
#else
|
||||
BINARY_IO_INLINE int
|
||||
set_binary_mode (int fd, int mode)
|
||||
{
|
||||
return __gl_setmode (fd, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This macro is obsolescent. */
|
||||
#define SET_BINARY(fd) ((void) set_binary_mode (fd, O_BINARY))
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif /* _BINARY_H */
|
|
@ -1,44 +0,0 @@
|
|||
/* byteswap.h - Byte swapping
|
||||
Copyright (C) 2005, 2007, 2009-2023 Free Software Foundation, Inc.
|
||||
Written by Oskar Liljeblad <oskar@osk.mine.nu>, 2005.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GL_BYTESWAP_H
|
||||
#define _GL_BYTESWAP_H
|
||||
|
||||
/* Given an unsigned 16-bit argument X, return the value corresponding to
|
||||
X with reversed byte order. */
|
||||
#define bswap_16(x) ((((x) & 0x00FF) << 8) | \
|
||||
(((x) & 0xFF00) >> 8))
|
||||
|
||||
/* Given an unsigned 32-bit argument X, return the value corresponding to
|
||||
X with reversed byte order. */
|
||||
#define bswap_32(x) ((((x) & 0x000000FF) << 24) | \
|
||||
(((x) & 0x0000FF00) << 8) | \
|
||||
(((x) & 0x00FF0000) >> 8) | \
|
||||
(((x) & 0xFF000000) >> 24))
|
||||
|
||||
/* Given an unsigned 64-bit argument X, return the value corresponding to
|
||||
X with reversed byte order. */
|
||||
#define bswap_64(x) ((((x) & 0x00000000000000FFULL) << 56) | \
|
||||
(((x) & 0x000000000000FF00ULL) << 40) | \
|
||||
(((x) & 0x0000000000FF0000ULL) << 24) | \
|
||||
(((x) & 0x00000000FF000000ULL) << 8) | \
|
||||
(((x) & 0x000000FF00000000ULL) >> 8) | \
|
||||
(((x) & 0x0000FF0000000000ULL) >> 24) | \
|
||||
(((x) & 0x00FF000000000000ULL) >> 40) | \
|
||||
(((x) & 0xFF00000000000000ULL) >> 56))
|
||||
|
||||
#endif /* _GL_BYTESWAP_H */
|
|
@ -1,331 +0,0 @@
|
|||
/* C++ compatible function declaration macros.
|
||||
Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GL_CXXDEFS_H
|
||||
#define _GL_CXXDEFS_H
|
||||
|
||||
/* Begin/end the GNULIB_NAMESPACE namespace. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
|
||||
# define _GL_END_NAMESPACE }
|
||||
#else
|
||||
# define _GL_BEGIN_NAMESPACE
|
||||
# define _GL_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
/* The three most frequent use cases of these macros are:
|
||||
|
||||
* For providing a substitute for a function that is missing on some
|
||||
platforms, but is declared and works fine on the platforms on which
|
||||
it exists:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if !@HAVE_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on all platforms,
|
||||
but is broken/insufficient and needs to be replaced on some platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on some platforms
|
||||
but is broken/insufficient and needs to be replaced on some of them and
|
||||
is additionally either missing or undeclared on some other platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
# if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* _GL_EXTERN_C declaration;
|
||||
performs the declaration with C linkage. */
|
||||
#if defined __cplusplus
|
||||
# define _GL_EXTERN_C extern "C"
|
||||
#else
|
||||
# define _GL_EXTERN_C extern
|
||||
#endif
|
||||
|
||||
/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
|
||||
declares a replacement function, named rpl_func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
|
||||
_GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
|
||||
#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype rpl_func parameters_and_attributes
|
||||
|
||||
/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
|
||||
declares the system function, named func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype func parameters_and_attributes
|
||||
|
||||
/* _GL_CXXALIAS_RPL (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
|
||||
|
||||
Wrapping rpl_func in an object with an inline conversion operator
|
||||
avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
|
||||
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::rpl_func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_MDA (func, rettype, parameters);
|
||||
is to be used when func is a Microsoft deprecated alias, on native Windows.
|
||||
It declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to _func, if GNULIB_NAMESPACE is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
|
||||
*/
|
||||
#define _GL_CXXALIAS_MDA(func,rettype,parameters) \
|
||||
_GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)
|
||||
|
||||
/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
|
||||
except that the C function rpl_func may have a slightly different
|
||||
declaration. A cast is used to silence the "invalid conversion" error
|
||||
that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::rpl_func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_MDA (func, rettype, parameters);
|
||||
except that the C function func may have a slightly different declaration.
|
||||
A cast is used to silence the "invalid conversion" error that would
|
||||
otherwise occur. */
|
||||
#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \
|
||||
_GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)
|
||||
|
||||
/* _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to the system provided function func, if GNULIB_NAMESPACE
|
||||
is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
|
||||
|
||||
Wrapping func in an object with an inline conversion operator
|
||||
avoids a reference to func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function func may have a slightly different declaration.
|
||||
A cast is used to silence the "invalid conversion" error that would
|
||||
otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function is picked among a set of overloaded functions,
|
||||
namely the one with rettype2 and parameters2. Two consecutive casts
|
||||
are used to silence the "cannot find a match" and "invalid conversion"
|
||||
errors that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
/* The outer cast must be a reinterpret_cast.
|
||||
The inner cast: When the function is defined as a set of overloaded
|
||||
functions, it works as a static_cast<>, choosing the designated variant.
|
||||
When the function is defined as a single variant, it works as a
|
||||
reinterpret_cast<>. The parenthesized cast syntax works both ways. */
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN (func);
|
||||
causes a warning to be emitted when ::func is used but not when
|
||||
GNULIB_NAMESPACE::func is used. func must be defined without overloaded
|
||||
variants. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN_1(func,namespace) \
|
||||
_GL_CXXALIASWARN_2 (func, namespace)
|
||||
/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_WARN_ON_USE (func, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
extern __typeof__ (func) func
|
||||
# else
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
|
||||
causes a warning to be emitted when the given overloaded variant of ::func
|
||||
is used but not when GNULIB_NAMESPACE::func is used. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
|
||||
GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
|
||||
/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# else
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
#endif /* _GL_CXXDEFS_H */
|
|
@ -1,21 +0,0 @@
|
|||
/* Character handling in C locale.
|
||||
|
||||
Copyright (C) 2003-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define C_CTYPE_INLINE _GL_EXTERN_INLINE
|
||||
#include "c-ctype.h"
|
|
@ -1,364 +0,0 @@
|
|||
/* Character handling in C locale.
|
||||
|
||||
These functions work like the corresponding functions in <ctype.h>,
|
||||
except that they have the C (POSIX) locale hardwired, whereas the
|
||||
<ctype.h> functions' behaviour depends on the current locale set via
|
||||
setlocale.
|
||||
|
||||
Copyright (C) 2000-2003, 2006, 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef C_CTYPE_H
|
||||
#define C_CTYPE_H
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef C_CTYPE_INLINE
|
||||
# define C_CTYPE_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* The functions defined in this file assume the "C" locale and a character
|
||||
set without diacritics (ASCII-US or EBCDIC-US or something like that).
|
||||
Even if the "C" locale on a particular system is an extension of the ASCII
|
||||
character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
|
||||
is ISO-8859-1), the functions in this file recognize only the ASCII
|
||||
characters. */
|
||||
|
||||
|
||||
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
||||
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
||||
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
||||
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
||||
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
||||
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
||||
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
||||
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
||||
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
||||
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
||||
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
||||
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
||||
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
||||
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
||||
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
||||
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
||||
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
||||
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
||||
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
||||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
|
||||
/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
|
||||
Testing the value of '\n' and '\r' is not relevant. */
|
||||
# define C_CTYPE_ASCII 1
|
||||
#elif ! (' ' == '\x40' && '0' == '\xf0' \
|
||||
&& 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \
|
||||
&& 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2')
|
||||
# error "Only ASCII and EBCDIC are supported"
|
||||
#endif
|
||||
|
||||
#if 'A' < 0
|
||||
# error "EBCDIC and char is signed -- not supported"
|
||||
#endif
|
||||
|
||||
/* Cases for control characters. */
|
||||
|
||||
#define _C_CTYPE_CNTRL \
|
||||
case '\a': case '\b': case '\f': case '\n': \
|
||||
case '\r': case '\t': case '\v': \
|
||||
_C_CTYPE_OTHER_CNTRL
|
||||
|
||||
/* ASCII control characters other than those with \-letter escapes. */
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
# define _C_CTYPE_OTHER_CNTRL \
|
||||
case '\x00': case '\x01': case '\x02': case '\x03': \
|
||||
case '\x04': case '\x05': case '\x06': case '\x0e': \
|
||||
case '\x0f': case '\x10': case '\x11': case '\x12': \
|
||||
case '\x13': case '\x14': case '\x15': case '\x16': \
|
||||
case '\x17': case '\x18': case '\x19': case '\x1a': \
|
||||
case '\x1b': case '\x1c': case '\x1d': case '\x1e': \
|
||||
case '\x1f': case '\x7f'
|
||||
#else
|
||||
/* Use EBCDIC code page 1047's assignments for ASCII control chars;
|
||||
assume all EBCDIC code pages agree about these assignments. */
|
||||
# define _C_CTYPE_OTHER_CNTRL \
|
||||
case '\x00': case '\x01': case '\x02': case '\x03': \
|
||||
case '\x07': case '\x0e': case '\x0f': case '\x10': \
|
||||
case '\x11': case '\x12': case '\x13': case '\x18': \
|
||||
case '\x19': case '\x1c': case '\x1d': case '\x1e': \
|
||||
case '\x1f': case '\x26': case '\x27': case '\x2d': \
|
||||
case '\x2e': case '\x32': case '\x37': case '\x3c': \
|
||||
case '\x3d': case '\x3f'
|
||||
#endif
|
||||
|
||||
/* Cases for lowercase hex letters, and lowercase letters, all offset by N. */
|
||||
|
||||
#define _C_CTYPE_LOWER_A_THRU_F_N(N) \
|
||||
case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \
|
||||
case 'e' + (N): case 'f' + (N)
|
||||
#define _C_CTYPE_LOWER_N(N) \
|
||||
_C_CTYPE_LOWER_A_THRU_F_N(N): \
|
||||
case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \
|
||||
case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \
|
||||
case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \
|
||||
case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \
|
||||
case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N)
|
||||
|
||||
/* Cases for hex letters, digits, lower, punct, and upper. */
|
||||
|
||||
#define _C_CTYPE_A_THRU_F \
|
||||
_C_CTYPE_LOWER_A_THRU_F_N (0): \
|
||||
_C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a')
|
||||
#define _C_CTYPE_DIGIT \
|
||||
case '0': case '1': case '2': case '3': \
|
||||
case '4': case '5': case '6': case '7': \
|
||||
case '8': case '9'
|
||||
#define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0)
|
||||
#define _C_CTYPE_PUNCT \
|
||||
case '!': case '"': case '#': case '$': \
|
||||
case '%': case '&': case '\'': case '(': \
|
||||
case ')': case '*': case '+': case ',': \
|
||||
case '-': case '.': case '/': case ':': \
|
||||
case ';': case '<': case '=': case '>': \
|
||||
case '?': case '@': case '[': case '\\': \
|
||||
case ']': case '^': case '_': case '`': \
|
||||
case '{': case '|': case '}': case '~'
|
||||
#define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a')
|
||||
|
||||
|
||||
/* Function definitions. */
|
||||
|
||||
/* Unlike the functions in <ctype.h>, which require an argument in the range
|
||||
of the 'unsigned char' type, the functions here operate on values that are
|
||||
in the 'unsigned char' range or in the 'char' range. In other words,
|
||||
when you have a 'char' value, you need to cast it before using it as
|
||||
argument to a <ctype.h> function:
|
||||
|
||||
const char *s = ...;
|
||||
if (isalpha ((unsigned char) *s)) ...
|
||||
|
||||
but you don't need to cast it for the functions defined in this file:
|
||||
|
||||
const char *s = ...;
|
||||
if (c_isalpha (*s)) ...
|
||||
*/
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isalnum (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isalpha (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* The function isascii is not locale dependent.
|
||||
Its use in EBCDIC is questionable. */
|
||||
C_CTYPE_INLINE bool
|
||||
c_isascii (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ':
|
||||
_C_CTYPE_CNTRL:
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_PUNCT:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isblank (int c)
|
||||
{
|
||||
return c == ' ' || c == '\t';
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_iscntrl (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_CNTRL:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isdigit (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isgraph (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_PUNCT:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_islower (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_LOWER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isprint (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ':
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_PUNCT:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_ispunct (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_PUNCT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isspace (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isupper (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isxdigit (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_A_THRU_F:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE int
|
||||
c_tolower (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_UPPER:
|
||||
return c - 'A' + 'a';
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE int
|
||||
c_toupper (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_LOWER:
|
||||
return c - 'a' + 'A';
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif /* C_CTYPE_H */
|
|
@ -1,56 +0,0 @@
|
|||
/* Case-insensitive string comparison functions in C locale.
|
||||
Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2023 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef C_STRCASE_H
|
||||
#define C_STRCASE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* The functions defined in this file assume the "C" locale and a character
|
||||
set without diacritics (ASCII-US or EBCDIC-US or something like that).
|
||||
Even if the "C" locale on a particular system is an extension of the ASCII
|
||||
character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
|
||||
is ISO-8859-1), the functions in this file recognize only the ASCII
|
||||
characters. More precisely, one of the string arguments must be an ASCII
|
||||
string; the other one can also contain non-ASCII characters (but then
|
||||
the comparison result will be nonzero). */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
|
||||
greater than zero if S1 is lexicographically less than, equal to or greater
|
||||
than S2. */
|
||||
extern int c_strcasecmp (const char *s1, const char *s2) _GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Compare no more than N characters of strings S1 and S2, ignoring case,
|
||||
returning less than, equal to or greater than zero if S1 is
|
||||
lexicographically less than, equal to or greater than S2. */
|
||||
extern int c_strncasecmp (const char *s1, const char *s2, size_t n)
|
||||
_GL_ATTRIBUTE_PURE;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* C_STRCASE_H */
|
|
@ -1,56 +0,0 @@
|
|||
/* c-strcasecmp.c -- case insensitive string comparator in C locale
|
||||
Copyright (C) 1998-1999, 2005-2006, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "c-strcase.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "c-ctype.h"
|
||||
|
||||
int
|
||||
c_strcasecmp (const char *s1, const char *s2)
|
||||
{
|
||||
register const unsigned char *p1 = (const unsigned char *) s1;
|
||||
register const unsigned char *p2 = (const unsigned char *) s2;
|
||||
unsigned char c1, c2;
|
||||
|
||||
if (p1 == p2)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
c1 = c_tolower (*p1);
|
||||
c2 = c_tolower (*p2);
|
||||
|
||||
if (c1 == '\0')
|
||||
break;
|
||||
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
if (UCHAR_MAX <= INT_MAX)
|
||||
return c1 - c2;
|
||||
else
|
||||
/* On machines where 'char' and 'int' are types of the same size, the
|
||||
difference of two 'unsigned char' values - including the sign bit -
|
||||
doesn't fit in an 'int'. */
|
||||
return _GL_CMP (c1, c2);
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/* c-strncasecmp.c -- case insensitive string comparator in C locale
|
||||
Copyright (C) 1998-1999, 2005-2006, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "c-strcase.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "c-ctype.h"
|
||||
|
||||
int
|
||||
c_strncasecmp (const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
register const unsigned char *p1 = (const unsigned char *) s1;
|
||||
register const unsigned char *p2 = (const unsigned char *) s2;
|
||||
unsigned char c1, c2;
|
||||
|
||||
if (p1 == p2 || n == 0)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
c1 = c_tolower (*p1);
|
||||
c2 = c_tolower (*p2);
|
||||
|
||||
if (--n == 0 || c1 == '\0')
|
||||
break;
|
||||
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
if (UCHAR_MAX <= INT_MAX)
|
||||
return c1 - c2;
|
||||
else
|
||||
/* On machines where 'char' and 'int' are types of the same size, the
|
||||
difference of two 'unsigned char' values - including the sign bit -
|
||||
doesn't fit in an 'int'. */
|
||||
return _GL_CMP (c1, c2);
|
||||
}
|
|
@ -1,469 +0,0 @@
|
|||
/* Return the canonical absolute name of a given file.
|
||||
Copyright (C) 1996-2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _LIBC
|
||||
/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
|
||||
optimizes away the name == NULL test below. */
|
||||
# define _GL_ARG_NONNULL(params)
|
||||
|
||||
# include <libc-config.h>
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <eloop-threshold.h>
|
||||
#include <filename.h>
|
||||
#include <idx.h>
|
||||
#include <intprops.h>
|
||||
#include <scratch_buffer.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <shlib-compat.h>
|
||||
# define GCC_LINT 1
|
||||
# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
|
||||
#else
|
||||
# define __canonicalize_file_name canonicalize_file_name
|
||||
# define __realpath realpath
|
||||
# define __strdup strdup
|
||||
# include "pathmax.h"
|
||||
# define __faccessat faccessat
|
||||
# if defined _WIN32 && !defined __CYGWIN__
|
||||
# define __getcwd _getcwd
|
||||
# elif HAVE_GETCWD
|
||||
# if IN_RELOCWRAPPER
|
||||
/* When building the relocatable program wrapper, use the system's getcwd
|
||||
function, not the gnulib override, otherwise we would get a link error.
|
||||
*/
|
||||
# undef getcwd
|
||||
# endif
|
||||
# if defined VMS && !defined getcwd
|
||||
/* We want the directory in Unix syntax, not in VMS syntax.
|
||||
The gnulib override of 'getcwd' takes 2 arguments; the original VMS
|
||||
'getcwd' takes 3 arguments. */
|
||||
# define __getcwd(buf, max) getcwd (buf, max, 0)
|
||||
# else
|
||||
# define __getcwd getcwd
|
||||
# endif
|
||||
# else
|
||||
# define __getcwd(buf, max) getwd (buf)
|
||||
# endif
|
||||
# define __mempcpy mempcpy
|
||||
# define __pathconf pathconf
|
||||
# define __rawmemchr rawmemchr
|
||||
# define __readlink readlink
|
||||
# if IN_RELOCWRAPPER
|
||||
/* When building the relocatable program wrapper, use the system's memmove
|
||||
function, not the gnulib override, otherwise we would get a link error.
|
||||
*/
|
||||
# undef memmove
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Suppress bogus GCC -Wmaybe-uninitialized warnings. */
|
||||
#if defined GCC_LINT || defined lint
|
||||
# define IF_LINT(Code) Code
|
||||
#else
|
||||
# define IF_LINT(Code) /* empty */
|
||||
#endif
|
||||
|
||||
#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||
# define DOUBLE_SLASH_IS_DISTINCT_ROOT false
|
||||
#endif
|
||||
|
||||
#if defined _LIBC || !FUNC_REALPATH_WORKS
|
||||
|
||||
/* Return true if FILE's existence can be shown, false (setting errno)
|
||||
otherwise. Follow symbolic links. */
|
||||
static bool
|
||||
file_accessible (char const *file)
|
||||
{
|
||||
# if defined _LIBC || HAVE_FACCESSAT
|
||||
return __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS) == 0;
|
||||
# else
|
||||
struct stat st;
|
||||
return stat (file, &st) == 0 || errno == EOVERFLOW;
|
||||
# endif
|
||||
}
|
||||
|
||||
/* True if concatenating END as a suffix to a file name means that the
|
||||
code needs to check that the file name is that of a searchable
|
||||
directory, since the canonicalize_filename_mode_stk code won't
|
||||
check this later anyway when it checks an ordinary file name
|
||||
component within END. END must either be empty, or start with a
|
||||
slash. */
|
||||
|
||||
static bool _GL_ATTRIBUTE_PURE
|
||||
suffix_requires_dir_check (char const *end)
|
||||
{
|
||||
/* If END does not start with a slash, the suffix is OK. */
|
||||
while (ISSLASH (*end))
|
||||
{
|
||||
/* Two or more slashes act like a single slash. */
|
||||
do
|
||||
end++;
|
||||
while (ISSLASH (*end));
|
||||
|
||||
switch (*end++)
|
||||
{
|
||||
default: return false; /* An ordinary file name component is OK. */
|
||||
case '\0': return true; /* Trailing "/" is trouble. */
|
||||
case '.': break; /* Possibly "." or "..". */
|
||||
}
|
||||
/* Trailing "/.", or "/.." even if not trailing, is trouble. */
|
||||
if (!*end || (*end == '.' && (!end[1] || ISSLASH (end[1]))))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Append this to a file name to test whether it is a searchable directory.
|
||||
On POSIX platforms "/" suffices, but "/./" is sometimes needed on
|
||||
macOS 10.13 <https://bugs.gnu.org/30350>, and should also work on
|
||||
platforms like AIX 7.2 that need at least "/.". */
|
||||
|
||||
# if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||
static char const dir_suffix[] = "/";
|
||||
# else
|
||||
static char const dir_suffix[] = "/./";
|
||||
# endif
|
||||
|
||||
/* Return true if DIR is a searchable dir, false (setting errno) otherwise.
|
||||
DIREND points to the NUL byte at the end of the DIR string.
|
||||
Store garbage into DIREND[0 .. strlen (dir_suffix)]. */
|
||||
|
||||
static bool
|
||||
dir_check (char *dir, char *dirend)
|
||||
{
|
||||
strcpy (dirend, dir_suffix);
|
||||
return file_accessible (dir);
|
||||
}
|
||||
|
||||
static idx_t
|
||||
get_path_max (void)
|
||||
{
|
||||
# ifdef PATH_MAX
|
||||
long int path_max = PATH_MAX;
|
||||
# else
|
||||
/* The caller invoked realpath with a null RESOLVED, even though
|
||||
PATH_MAX is not defined as a constant. The glibc manual says
|
||||
programs should not do this, and POSIX says the behavior is undefined.
|
||||
Historically, glibc here used the result of pathconf, or 1024 if that
|
||||
failed; stay consistent with this (dubious) historical practice. */
|
||||
int err = errno;
|
||||
long int path_max = __pathconf ("/", _PC_PATH_MAX);
|
||||
__set_errno (err);
|
||||
# endif
|
||||
return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX;
|
||||
}
|
||||
|
||||
/* Scratch buffers used by realpath_stk and managed by __realpath. */
|
||||
struct realpath_bufs
|
||||
{
|
||||
struct scratch_buffer rname;
|
||||
struct scratch_buffer extra;
|
||||
struct scratch_buffer link;
|
||||
};
|
||||
|
||||
static char *
|
||||
realpath_stk (const char *name, char *resolved, struct realpath_bufs *bufs)
|
||||
{
|
||||
char *dest;
|
||||
char const *start;
|
||||
char const *end;
|
||||
int num_links = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
char *rname = bufs->rname.data;
|
||||
bool end_in_extra_buffer = false;
|
||||
bool failed = true;
|
||||
|
||||
/* This is always zero for Posix hosts, but can be 2 for MS-Windows
|
||||
and MS-DOS X:/foo/bar file names. */
|
||||
idx_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
|
||||
|
||||
if (!IS_ABSOLUTE_FILE_NAME (name))
|
||||
{
|
||||
while (!__getcwd (bufs->rname.data, bufs->rname.length))
|
||||
{
|
||||
if (errno != ERANGE)
|
||||
{
|
||||
dest = rname;
|
||||
goto error;
|
||||
}
|
||||
if (!scratch_buffer_grow (&bufs->rname))
|
||||
return NULL;
|
||||
rname = bufs->rname.data;
|
||||
}
|
||||
dest = __rawmemchr (rname, '\0');
|
||||
start = name;
|
||||
prefix_len = FILE_SYSTEM_PREFIX_LEN (rname);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = __mempcpy (rname, name, prefix_len);
|
||||
*dest++ = '/';
|
||||
if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
|
||||
{
|
||||
if (prefix_len == 0 /* implies ISSLASH (name[0]) */
|
||||
&& ISSLASH (name[1]) && !ISSLASH (name[2]))
|
||||
*dest++ = '/';
|
||||
*dest = '\0';
|
||||
}
|
||||
start = name + prefix_len;
|
||||
}
|
||||
|
||||
for ( ; *start; start = end)
|
||||
{
|
||||
/* Skip sequence of multiple file name separators. */
|
||||
while (ISSLASH (*start))
|
||||
++start;
|
||||
|
||||
/* Find end of component. */
|
||||
for (end = start; *end && !ISSLASH (*end); ++end)
|
||||
/* Nothing. */;
|
||||
|
||||
/* Length of this file name component; it can be zero if a file
|
||||
name ends in '/'. */
|
||||
idx_t startlen = end - start;
|
||||
|
||||
if (startlen == 0)
|
||||
break;
|
||||
else if (startlen == 1 && start[0] == '.')
|
||||
/* nothing */;
|
||||
else if (startlen == 2 && start[0] == '.' && start[1] == '.')
|
||||
{
|
||||
/* Back up to previous component, ignore if at root already. */
|
||||
if (dest > rname + prefix_len + 1)
|
||||
for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
|
||||
continue;
|
||||
if (DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||
&& dest == rname + 1 && !prefix_len
|
||||
&& ISSLASH (*dest) && !ISSLASH (dest[1]))
|
||||
dest++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ISSLASH (dest[-1]))
|
||||
*dest++ = '/';
|
||||
|
||||
while (rname + bufs->rname.length - dest
|
||||
< startlen + sizeof dir_suffix)
|
||||
{
|
||||
idx_t dest_offset = dest - rname;
|
||||
if (!scratch_buffer_grow_preserve (&bufs->rname))
|
||||
return NULL;
|
||||
rname = bufs->rname.data;
|
||||
dest = rname + dest_offset;
|
||||
}
|
||||
|
||||
dest = __mempcpy (dest, start, startlen);
|
||||
*dest = '\0';
|
||||
|
||||
char *buf;
|
||||
ssize_t n;
|
||||
while (true)
|
||||
{
|
||||
buf = bufs->link.data;
|
||||
idx_t bufsize = bufs->link.length;
|
||||
n = __readlink (rname, buf, bufsize - 1);
|
||||
if (n < bufsize - 1)
|
||||
break;
|
||||
if (!scratch_buffer_grow (&bufs->link))
|
||||
return NULL;
|
||||
}
|
||||
if (0 <= n)
|
||||
{
|
||||
if (++num_links > __eloop_threshold ())
|
||||
{
|
||||
__set_errno (ELOOP);
|
||||
goto error;
|
||||
}
|
||||
|
||||
buf[n] = '\0';
|
||||
|
||||
char *extra_buf = bufs->extra.data;
|
||||
idx_t end_idx IF_LINT (= 0);
|
||||
if (end_in_extra_buffer)
|
||||
end_idx = end - extra_buf;
|
||||
size_t len = strlen (end);
|
||||
if (INT_ADD_OVERFLOW (len, n))
|
||||
{
|
||||
__set_errno (ENOMEM);
|
||||
return NULL;
|
||||
}
|
||||
while (bufs->extra.length <= len + n)
|
||||
{
|
||||
if (!scratch_buffer_grow_preserve (&bufs->extra))
|
||||
return NULL;
|
||||
extra_buf = bufs->extra.data;
|
||||
}
|
||||
if (end_in_extra_buffer)
|
||||
end = extra_buf + end_idx;
|
||||
|
||||
/* Careful here, end may be a pointer into extra_buf... */
|
||||
memmove (&extra_buf[n], end, len + 1);
|
||||
name = end = memcpy (extra_buf, buf, n);
|
||||
end_in_extra_buffer = true;
|
||||
|
||||
if (IS_ABSOLUTE_FILE_NAME (buf))
|
||||
{
|
||||
idx_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
|
||||
|
||||
dest = __mempcpy (rname, buf, pfxlen);
|
||||
*dest++ = '/'; /* It's an absolute symlink */
|
||||
if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
|
||||
{
|
||||
if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
|
||||
*dest++ = '/';
|
||||
*dest = '\0';
|
||||
}
|
||||
/* Install the new prefix to be in effect hereafter. */
|
||||
prefix_len = pfxlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Back up to previous component, ignore if at root
|
||||
already: */
|
||||
if (dest > rname + prefix_len + 1)
|
||||
for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
|
||||
continue;
|
||||
if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
|
||||
&& ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
else if (! (suffix_requires_dir_check (end)
|
||||
? dir_check (rname, dest)
|
||||
: errno == EINVAL))
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1]))
|
||||
--dest;
|
||||
if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len
|
||||
&& ISSLASH (*dest) && !ISSLASH (dest[1]))
|
||||
dest++;
|
||||
failed = false;
|
||||
|
||||
error:
|
||||
*dest++ = '\0';
|
||||
if (resolved != NULL)
|
||||
{
|
||||
/* Copy the full result on success or partial result if failure was due
|
||||
to the path not existing or not being accessible. */
|
||||
if ((!failed || errno == ENOENT || errno == EACCES)
|
||||
&& dest - rname <= get_path_max ())
|
||||
{
|
||||
strcpy (resolved, rname);
|
||||
if (failed)
|
||||
return NULL;
|
||||
else
|
||||
return resolved;
|
||||
}
|
||||
if (!failed)
|
||||
__set_errno (ENAMETOOLONG);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (failed)
|
||||
return NULL;
|
||||
else
|
||||
return __strdup (bufs->rname.data);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 file name 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 name of the first component
|
||||
that cannot be resolved. If the name can be resolved, RESOLVED
|
||||
holds the same value as the value returned. */
|
||||
|
||||
char *
|
||||
__realpath (const char *name, char *resolved)
|
||||
{
|
||||
struct realpath_bufs bufs;
|
||||
scratch_buffer_init (&bufs.rname);
|
||||
scratch_buffer_init (&bufs.extra);
|
||||
scratch_buffer_init (&bufs.link);
|
||||
char *result = realpath_stk (name, resolved, &bufs);
|
||||
scratch_buffer_free (&bufs.link);
|
||||
scratch_buffer_free (&bufs.extra);
|
||||
scratch_buffer_free (&bufs.rname);
|
||||
return result;
|
||||
}
|
||||
libc_hidden_def (__realpath)
|
||||
versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
|
||||
|
||||
#endif /* defined _LIBC || !FUNC_REALPATH_WORKS */
|
||||
|
||||
|
||||
#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
|
||||
char *
|
||||
attribute_compat_text_section
|
||||
__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)
|
|
@ -1,184 +0,0 @@
|
|||
/* Read symbolic links into a buffer without size limitation, relative to fd.
|
||||
|
||||
Copyright (C) 2001, 2003-2004, 2007, 2009-2023 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "careadlinkat.h"
|
||||
|
||||
#include "idx.h"
|
||||
#include "minmax.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Define this independently so that stdint.h is not a prerequisite. */
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t) -1)
|
||||
#endif
|
||||
|
||||
#ifndef SSIZE_MAX
|
||||
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
|
||||
#endif
|
||||
|
||||
#include "allocator.h"
|
||||
|
||||
enum { STACK_BUF_SIZE = 1024 };
|
||||
|
||||
/* Act like careadlinkat (see below), with an additional argument
|
||||
STACK_BUF that can be used as temporary storage.
|
||||
|
||||
If GCC_LINT is defined, do not inline this function with GCC 10.1
|
||||
and later, to avoid creating a pointer to the stack that GCC
|
||||
-Wreturn-local-addr incorrectly complains about. See:
|
||||
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644
|
||||
Although the noinline attribute can hurt performance a bit, no better way
|
||||
to pacify GCC is known; even an explicit #pragma does not pacify GCC.
|
||||
When the GCC bug is fixed this workaround should be limited to the
|
||||
broken GCC versions. */
|
||||
#if _GL_GNUC_PREREQ (10, 1)
|
||||
# if defined GCC_LINT || defined lint
|
||||
__attribute__ ((__noinline__))
|
||||
# elif __OPTIMIZE__ && !__NO_INLINE__
|
||||
# define GCC_BOGUS_WRETURN_LOCAL_ADDR
|
||||
# endif
|
||||
#endif
|
||||
static char *
|
||||
readlink_stk (int fd, char const *filename,
|
||||
char *buffer, size_t buffer_size,
|
||||
struct allocator const *alloc,
|
||||
ssize_t (*preadlinkat) (int, char const *, char *, size_t),
|
||||
char stack_buf[STACK_BUF_SIZE])
|
||||
{
|
||||
if (! alloc)
|
||||
alloc = &stdlib_allocator;
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
buffer = stack_buf;
|
||||
buffer_size = STACK_BUF_SIZE;
|
||||
}
|
||||
|
||||
char *buf = buffer;
|
||||
idx_t buf_size_max = MIN (IDX_MAX, MIN (SSIZE_MAX, SIZE_MAX));
|
||||
idx_t buf_size = MIN (buffer_size, buf_size_max);
|
||||
|
||||
while (buf)
|
||||
{
|
||||
/* Attempt to read the link into the current buffer. */
|
||||
idx_t link_length = preadlinkat (fd, filename, buf, buf_size);
|
||||
if (link_length < 0)
|
||||
{
|
||||
if (buf != buffer)
|
||||
{
|
||||
int readlinkat_errno = errno;
|
||||
alloc->free (buf);
|
||||
errno = readlinkat_errno;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
idx_t link_size = link_length;
|
||||
|
||||
if (link_size < buf_size)
|
||||
{
|
||||
buf[link_size++] = '\0';
|
||||
|
||||
if (buf == stack_buf)
|
||||
{
|
||||
char *b = alloc->allocate (link_size);
|
||||
buf_size = link_size;
|
||||
if (! b)
|
||||
break;
|
||||
return memcpy (b, buf, link_size);
|
||||
}
|
||||
|
||||
if (link_size < buf_size && buf != buffer && alloc->reallocate)
|
||||
{
|
||||
/* Shrink BUF before returning it. */
|
||||
char *b = alloc->reallocate (buf, link_size);
|
||||
if (b)
|
||||
return b;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (buf != buffer)
|
||||
alloc->free (buf);
|
||||
|
||||
if (buf_size_max / 2 <= buf_size)
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf_size = 2 * buf_size + 1;
|
||||
buf = alloc->allocate (buf_size);
|
||||
}
|
||||
|
||||
if (alloc->die)
|
||||
alloc->die (buf_size);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Assuming the current directory is FD, get the symbolic link value
|
||||
of FILENAME as a null-terminated string and put it into a buffer.
|
||||
If FD is AT_FDCWD, FILENAME is interpreted relative to the current
|
||||
working directory, as in openat.
|
||||
|
||||
If the link is small enough to fit into BUFFER put it there.
|
||||
BUFFER's size is BUFFER_SIZE, and BUFFER can be null
|
||||
if BUFFER_SIZE is zero.
|
||||
|
||||
If the link is not small, put it into a dynamically allocated
|
||||
buffer managed by ALLOC. It is the caller's responsibility to free
|
||||
the returned value if it is nonnull and is not BUFFER. A null
|
||||
ALLOC stands for the standard allocator.
|
||||
|
||||
The PREADLINKAT function specifies how to read links. It operates
|
||||
like POSIX readlinkat()
|
||||
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>
|
||||
but can assume that its first argument is the same as FD.
|
||||
|
||||
If successful, return the buffer address; otherwise return NULL and
|
||||
set errno. */
|
||||
|
||||
char *
|
||||
careadlinkat (int fd, char const *filename,
|
||||
char *buffer, size_t buffer_size,
|
||||
struct allocator const *alloc,
|
||||
ssize_t (*preadlinkat) (int, char const *, char *, size_t))
|
||||
{
|
||||
/* Allocate the initial buffer on the stack. This way, in the
|
||||
common case of a symlink of small size, we get away with a
|
||||
single small malloc instead of a big malloc followed by a
|
||||
shrinking realloc. */
|
||||
#ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR
|
||||
#warning "GCC might issue a bogus -Wreturn-local-addr warning here."
|
||||
#warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>."
|
||||
#endif
|
||||
char stack_buf[STACK_BUF_SIZE];
|
||||
return readlink_stk (fd, filename, buffer, buffer_size, alloc,
|
||||
preadlinkat, stack_buf);
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/* Read symbolic links into a buffer without size limitation, relative to fd.
|
||||
|
||||
Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
|
||||
|
||||
#ifndef _GL_CAREADLINKAT_H
|
||||
#define _GL_CAREADLINKAT_H
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct allocator;
|
||||
|
||||
/* Assuming the current directory is FD, get the symbolic link value
|
||||
of FILENAME as a null-terminated string and put it into a buffer.
|
||||
If FD is AT_FDCWD, FILENAME is interpreted relative to the current
|
||||
working directory, as in openat.
|
||||
|
||||
If the link is small enough to fit into BUFFER put it there.
|
||||
BUFFER's size is BUFFER_SIZE, and BUFFER can be null
|
||||
if BUFFER_SIZE is zero.
|
||||
|
||||
If the link is not small, put it into a dynamically allocated
|
||||
buffer managed by ALLOC. It is the caller's responsibility to free
|
||||
the returned value if it is nonnull and is not BUFFER.
|
||||
|
||||
The PREADLINKAT function specifies how to read links. It operates
|
||||
like POSIX readlinkat()
|
||||
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>
|
||||
but can assume that its first argument is the same as FD.
|
||||
|
||||
If successful, return the buffer address; otherwise return NULL and
|
||||
set errno. */
|
||||
|
||||
char *careadlinkat (int fd, char const *filename,
|
||||
char *restrict buffer, size_t buffer_size,
|
||||
struct allocator const *alloc,
|
||||
ssize_t (*preadlinkat) (int, char const *,
|
||||
char *, size_t));
|
||||
|
||||
/* Suitable value for careadlinkat's FD argument. */
|
||||
#if HAVE_READLINKAT
|
||||
/* AT_FDCWD is declared in <fcntl.h>. */
|
||||
#else
|
||||
/* Define AT_FDCWD independently, so that the careadlinkat module does
|
||||
not depend on the fcntl-h module. We might as well use the same value
|
||||
as fcntl-h. */
|
||||
# ifndef AT_FDCWD
|
||||
# define AT_FDCWD (-3041965)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* _GL_CAREADLINKAT_H */
|
|
@ -1,715 +0,0 @@
|
|||
/* Copyright (C) 1992-2023 Free Software Foundation, Inc.
|
||||
Copyright The GNU Toolchain Authors.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _SYS_CDEFS_H
|
||||
#define _SYS_CDEFS_H 1
|
||||
|
||||
/* We are almost always included from features.h. */
|
||||
#ifndef _FEATURES_H
|
||||
# include <features.h>
|
||||
#endif
|
||||
|
||||
/* The GNU libc does not support any K&R compilers or the traditional mode
|
||||
of ISO C compilers anymore. Check for some of the combinations not
|
||||
supported anymore. */
|
||||
#if defined __GNUC__ && !defined __STDC__
|
||||
# error "You need a ISO C conforming compiler to use the glibc headers"
|
||||
#endif
|
||||
|
||||
/* Some user header file might have defined this before. */
|
||||
#undef __P
|
||||
#undef __PMT
|
||||
|
||||
/* Compilers that lack __has_attribute may object to
|
||||
#if defined __has_attribute && __has_attribute (...)
|
||||
even though they do not need to evaluate the right-hand side of the &&.
|
||||
Similarly for __has_builtin, etc. */
|
||||
#if (defined __has_attribute \
|
||||
&& (!defined __clang_minor__ \
|
||||
|| (defined __apple_build_version__ \
|
||||
? 6000000 <= __apple_build_version__ \
|
||||
: 3 < __clang_major__ + (5 <= __clang_minor__))))
|
||||
# define __glibc_has_attribute(attr) __has_attribute (attr)
|
||||
#else
|
||||
# define __glibc_has_attribute(attr) 0
|
||||
#endif
|
||||
#ifdef __has_builtin
|
||||
# define __glibc_has_builtin(name) __has_builtin (name)
|
||||
#else
|
||||
# define __glibc_has_builtin(name) 0
|
||||
#endif
|
||||
#ifdef __has_extension
|
||||
# define __glibc_has_extension(ext) __has_extension (ext)
|
||||
#else
|
||||
# define __glibc_has_extension(ext) 0
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ || defined __clang__
|
||||
|
||||
/* All functions, except those with callbacks or those that
|
||||
synchronize memory, are leaf functions. */
|
||||
# if __GNUC_PREREQ (4, 6) && !defined _LIBC
|
||||
# define __LEAF , __leaf__
|
||||
# define __LEAF_ATTR __attribute__ ((__leaf__))
|
||||
# else
|
||||
# define __LEAF
|
||||
# define __LEAF_ATTR
|
||||
# endif
|
||||
|
||||
/* GCC can always grok prototypes. For C++ programs we add throw()
|
||||
to help it optimize the function calls. But this only works with
|
||||
gcc 2.8.x and egcs. For gcc 3.4 and up we even mark C functions
|
||||
as non-throwing using a function attribute since programs can use
|
||||
the -fexceptions options for C code as well. */
|
||||
# if !defined __cplusplus \
|
||||
&& (__GNUC_PREREQ (3, 4) || __glibc_has_attribute (__nothrow__))
|
||||
# define __THROW __attribute__ ((__nothrow__ __LEAF))
|
||||
# define __THROWNL __attribute__ ((__nothrow__))
|
||||
# define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct
|
||||
# define __NTHNL(fct) __attribute__ ((__nothrow__)) fct
|
||||
# else
|
||||
# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4)
|
||||
# if __cplusplus >= 201103L
|
||||
# define __THROW noexcept (true)
|
||||
# else
|
||||
# define __THROW throw ()
|
||||
# endif
|
||||
# define __THROWNL __THROW
|
||||
# define __NTH(fct) __LEAF_ATTR fct __THROW
|
||||
# define __NTHNL(fct) fct __THROW
|
||||
# else
|
||||
# define __THROW
|
||||
# define __THROWNL
|
||||
# define __NTH(fct) fct
|
||||
# define __NTHNL(fct) fct
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#else /* Not GCC or clang. */
|
||||
|
||||
# if (defined __cplusplus \
|
||||
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
|
||||
# define __inline inline
|
||||
# else
|
||||
# define __inline /* No inline functions. */
|
||||
# endif
|
||||
|
||||
# define __THROW
|
||||
# define __THROWNL
|
||||
# define __NTH(fct) fct
|
||||
|
||||
#endif /* GCC || clang. */
|
||||
|
||||
/* These two macros are not used in glibc anymore. They are kept here
|
||||
only because some other projects expect the macros to be defined. */
|
||||
#define __P(args) args
|
||||
#define __PMT(args) args
|
||||
|
||||
/* For these things, GCC behaves the ANSI way normally,
|
||||
and the non-ANSI way under -traditional. */
|
||||
|
||||
#define __CONCAT(x,y) x ## y
|
||||
#define __STRING(x) #x
|
||||
|
||||
/* This is not a typedef so `const __ptr_t' does the right thing. */
|
||||
#define __ptr_t void *
|
||||
|
||||
|
||||
/* C++ needs to know that types and declarations are C, not C++. */
|
||||
#ifdef __cplusplus
|
||||
# define __BEGIN_DECLS extern "C" {
|
||||
# define __END_DECLS }
|
||||
#else
|
||||
# define __BEGIN_DECLS
|
||||
# define __END_DECLS
|
||||
#endif
|
||||
|
||||
|
||||
/* Gnulib avoids these definitions, as they don't work on non-glibc platforms.
|
||||
In particular, __bos and __bos0 are defined differently in the Android libc.
|
||||
*/
|
||||
#ifndef __GNULIB_CDEFS
|
||||
|
||||
/* Fortify support. */
|
||||
# define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
|
||||
# define __bos0(ptr) __builtin_object_size (ptr, 0)
|
||||
|
||||
/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */
|
||||
# if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \
|
||||
|| __GNUC_PREREQ (12, 0))
|
||||
# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
|
||||
# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
|
||||
# else
|
||||
# define __glibc_objsize0(__o) __bos0 (__o)
|
||||
# define __glibc_objsize(__o) __bos (__o)
|
||||
# endif
|
||||
|
||||
/* Compile time conditions to choose between the regular, _chk and _chk_warn
|
||||
variants. These conditions should get evaluated to constant and optimized
|
||||
away. */
|
||||
|
||||
# define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s))
|
||||
# define __glibc_unsigned_or_positive(__l) \
|
||||
((__typeof (__l)) 0 < (__typeof (__l)) -1 \
|
||||
|| (__builtin_constant_p (__l) && (__l) > 0))
|
||||
|
||||
/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ
|
||||
condition can be folded to a constant and if it is true, or unknown (-1) */
|
||||
# define __glibc_safe_or_unknown_len(__l, __s, __osz) \
|
||||
((__osz) == (__SIZE_TYPE__) -1 \
|
||||
|| (__glibc_unsigned_or_positive (__l) \
|
||||
&& __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
|
||||
(__s), (__osz))) \
|
||||
&& __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz))))
|
||||
|
||||
/* Conversely, we know at compile time that the length is unsafe if the
|
||||
__L * __S <= __OBJSZ condition can be folded to a constant and if it is
|
||||
false. */
|
||||
# define __glibc_unsafe_len(__l, __s, __osz) \
|
||||
(__glibc_unsigned_or_positive (__l) \
|
||||
&& __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
|
||||
__s, __osz)) \
|
||||
&& !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
|
||||
|
||||
/* Fortify function f. __f_alias, __f_chk and __f_chk_warn must be
|
||||
declared. */
|
||||
|
||||
# define __glibc_fortify(f, __l, __s, __osz, ...) \
|
||||
(__glibc_safe_or_unknown_len (__l, __s, __osz) \
|
||||
? __ ## f ## _alias (__VA_ARGS__) \
|
||||
: (__glibc_unsafe_len (__l, __s, __osz) \
|
||||
? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \
|
||||
: __ ## f ## _chk (__VA_ARGS__, __osz))) \
|
||||
|
||||
/* Fortify function f, where object size argument passed to f is the number of
|
||||
elements and not total size. */
|
||||
|
||||
# define __glibc_fortify_n(f, __l, __s, __osz, ...) \
|
||||
(__glibc_safe_or_unknown_len (__l, __s, __osz) \
|
||||
? __ ## f ## _alias (__VA_ARGS__) \
|
||||
: (__glibc_unsafe_len (__l, __s, __osz) \
|
||||
? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \
|
||||
: __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) \
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if __GNUC_PREREQ (4,3)
|
||||
# define __warnattr(msg) __attribute__((__warning__ (msg)))
|
||||
# define __errordecl(name, msg) \
|
||||
extern void name (void) __attribute__((__error__ (msg)))
|
||||
#else
|
||||
# define __warnattr(msg)
|
||||
# define __errordecl(name, msg) extern void name (void)
|
||||
#endif
|
||||
|
||||
/* Support for flexible arrays.
|
||||
Headers that should use flexible arrays only if they're "real"
|
||||
(e.g. only if they won't affect sizeof()) should test
|
||||
#if __glibc_c99_flexarr_available. */
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __HP_cc
|
||||
# define __flexarr []
|
||||
# define __glibc_c99_flexarr_available 1
|
||||
#elif __GNUC_PREREQ (2,97) || defined __clang__
|
||||
/* GCC 2.97 and clang support C99 flexible array members as an extension,
|
||||
even when in C89 mode or compiling C++ (any version). */
|
||||
# define __flexarr []
|
||||
# define __glibc_c99_flexarr_available 1
|
||||
#elif defined __GNUC__
|
||||
/* Pre-2.97 GCC did not support C99 flexible arrays but did have
|
||||
an equivalent extension with slightly different notation. */
|
||||
# define __flexarr [0]
|
||||
# define __glibc_c99_flexarr_available 1
|
||||
#else
|
||||
/* Some other non-C99 compiler. Approximate with [1]. */
|
||||
# define __flexarr [1]
|
||||
# define __glibc_c99_flexarr_available 0
|
||||
#endif
|
||||
|
||||
|
||||
/* __asm__ ("xyz") is used throughout the headers to rename functions
|
||||
at the assembly language level. This is wrapped by the __REDIRECT
|
||||
macro, in order to support compilers that can do this some other
|
||||
way. When compilers don't support asm-names at all, we have to do
|
||||
preprocessor tricks instead (which don't have exactly the right
|
||||
semantics, but it's the best we can do).
|
||||
|
||||
Example:
|
||||
int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */
|
||||
|
||||
#if (defined __GNUC__ && __GNUC__ >= 2) || (__clang_major__ >= 4)
|
||||
|
||||
# define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))
|
||||
# ifdef __cplusplus
|
||||
# define __REDIRECT_NTH(name, proto, alias) \
|
||||
name proto __THROW __asm__ (__ASMNAME (#alias))
|
||||
# define __REDIRECT_NTHNL(name, proto, alias) \
|
||||
name proto __THROWNL __asm__ (__ASMNAME (#alias))
|
||||
# else
|
||||
# define __REDIRECT_NTH(name, proto, alias) \
|
||||
name proto __asm__ (__ASMNAME (#alias)) __THROW
|
||||
# define __REDIRECT_NTHNL(name, proto, alias) \
|
||||
name proto __asm__ (__ASMNAME (#alias)) __THROWNL
|
||||
# endif
|
||||
# define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
|
||||
# define __ASMNAME2(prefix, cname) __STRING (prefix) cname
|
||||
|
||||
/*
|
||||
#elif __SOME_OTHER_COMPILER__
|
||||
|
||||
# define __REDIRECT(name, proto, alias) name proto; \
|
||||
_Pragma("let " #name " = " #alias)
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* GCC and clang have various useful declarations that can be made with
|
||||
the '__attribute__' syntax. All of the ways we use this do fine if
|
||||
they are omitted for compilers that don't understand it. */
|
||||
#if !(defined __GNUC__ || defined __clang__)
|
||||
# define __attribute__(xyz) /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.96 development the `malloc' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__malloc__)
|
||||
# define __attribute_malloc__ __attribute__ ((__malloc__))
|
||||
#else
|
||||
# define __attribute_malloc__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* Tell the compiler which arguments to an allocation function
|
||||
indicate the size of the allocation. */
|
||||
#if __GNUC_PREREQ (4, 3)
|
||||
# define __attribute_alloc_size__(params) \
|
||||
__attribute__ ((__alloc_size__ params))
|
||||
#else
|
||||
# define __attribute_alloc_size__(params) /* Ignore. */
|
||||
#endif
|
||||
|
||||
/* Tell the compiler which argument to an allocation function
|
||||
indicates the alignment of the allocation. */
|
||||
#if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__alloc_align__)
|
||||
# define __attribute_alloc_align__(param) \
|
||||
__attribute__ ((__alloc_align__ param))
|
||||
#else
|
||||
# define __attribute_alloc_align__(param) /* Ignore. */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.96 development the `pure' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__pure__)
|
||||
# define __attribute_pure__ __attribute__ ((__pure__))
|
||||
#else
|
||||
# define __attribute_pure__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* This declaration tells the compiler that the value is constant. */
|
||||
#if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__)
|
||||
# define __attribute_const__ __attribute__ ((__const__))
|
||||
#else
|
||||
# define __attribute_const__ /* Ignore */
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__)
|
||||
# define __attribute_maybe_unused__ __attribute__ ((__unused__))
|
||||
#else
|
||||
# define __attribute_maybe_unused__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 3.1 development the `used' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (3,1) || __glibc_has_attribute (__used__)
|
||||
# define __attribute_used__ __attribute__ ((__used__))
|
||||
# define __attribute_noinline__ __attribute__ ((__noinline__))
|
||||
#else
|
||||
# define __attribute_used__ __attribute__ ((__unused__))
|
||||
# define __attribute_noinline__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* Since version 3.2, gcc allows marking deprecated functions. */
|
||||
#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__)
|
||||
# define __attribute_deprecated__ __attribute__ ((__deprecated__))
|
||||
#else
|
||||
# define __attribute_deprecated__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* Since version 4.5, gcc also allows one to specify the message printed
|
||||
when a deprecated function is used. clang claims to be gcc 4.2, but
|
||||
may also support this feature. */
|
||||
#if __GNUC_PREREQ (4,5) \
|
||||
|| __glibc_has_extension (__attribute_deprecated_with_message__)
|
||||
# define __attribute_deprecated_msg__(msg) \
|
||||
__attribute__ ((__deprecated__ (msg)))
|
||||
#else
|
||||
# define __attribute_deprecated_msg__(msg) __attribute_deprecated__
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.8 development the `format_arg' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings.
|
||||
If several `format_arg' attributes are given for the same function, in
|
||||
gcc-3.0 and older, all but the last one are ignored. In newer gccs,
|
||||
all designated arguments are considered. */
|
||||
#if __GNUC_PREREQ (2,8) || __glibc_has_attribute (__format_arg__)
|
||||
# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
|
||||
#else
|
||||
# define __attribute_format_arg__(x) /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.97 development the `strfmon' format
|
||||
attribute for functions was introduced. We don't want to use it
|
||||
unconditionally (although this would be possible) since it
|
||||
generates warnings. */
|
||||
#if __GNUC_PREREQ (2,97) || __glibc_has_attribute (__format__)
|
||||
# define __attribute_format_strfmon__(a,b) \
|
||||
__attribute__ ((__format__ (__strfmon__, a, b)))
|
||||
#else
|
||||
# define __attribute_format_strfmon__(a,b) /* Ignore */
|
||||
#endif
|
||||
|
||||
/* The nonnull function attribute marks pointer parameters that
|
||||
must not be NULL. This has the name __nonnull in glibc,
|
||||
and __attribute_nonnull__ in files shared with Gnulib to avoid
|
||||
collision with a different __nonnull in DragonFlyBSD 5.9. */
|
||||
#ifndef __attribute_nonnull__
|
||||
# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__)
|
||||
# define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params))
|
||||
# else
|
||||
# define __attribute_nonnull__(params)
|
||||
# endif
|
||||
#endif
|
||||
#ifndef __nonnull
|
||||
# define __nonnull(params) __attribute_nonnull__ (params)
|
||||
#endif
|
||||
|
||||
/* The returns_nonnull function attribute marks the return type of the function
|
||||
as always being non-null. */
|
||||
#ifndef __returns_nonnull
|
||||
# if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__returns_nonnull__)
|
||||
# define __returns_nonnull __attribute__ ((__returns_nonnull__))
|
||||
# else
|
||||
# define __returns_nonnull
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If fortification mode, we warn about unused results of certain
|
||||
function calls which can lead to problems. */
|
||||
#if __GNUC_PREREQ (3,4) || __glibc_has_attribute (__warn_unused_result__)
|
||||
# define __attribute_warn_unused_result__ \
|
||||
__attribute__ ((__warn_unused_result__))
|
||||
# if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0
|
||||
# define __wur __attribute_warn_unused_result__
|
||||
# endif
|
||||
#else
|
||||
# define __attribute_warn_unused_result__ /* empty */
|
||||
#endif
|
||||
#ifndef __wur
|
||||
# define __wur /* Ignore */
|
||||
#endif
|
||||
|
||||
/* Forces a function to be always inlined. */
|
||||
#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__always_inline__)
|
||||
/* The Linux kernel defines __always_inline in stddef.h (283d7573), and
|
||||
it conflicts with this definition. Therefore undefine it first to
|
||||
allow either header to be included first. */
|
||||
# undef __always_inline
|
||||
# define __always_inline __inline __attribute__ ((__always_inline__))
|
||||
#else
|
||||
# undef __always_inline
|
||||
# define __always_inline __inline
|
||||
#endif
|
||||
|
||||
/* Associate error messages with the source location of the call site rather
|
||||
than with the source location inside the function. */
|
||||
#if __GNUC_PREREQ (4,3) || __glibc_has_attribute (__artificial__)
|
||||
# define __attribute_artificial__ __attribute__ ((__artificial__))
|
||||
#else
|
||||
# define __attribute_artificial__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
|
||||
inline semantics, unless -fgnu89-inline is used. Using __GNUC_STDC_INLINE__
|
||||
or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions
|
||||
older than 4.3 may define these macros and still not guarantee GNU inlining
|
||||
semantics.
|
||||
|
||||
clang++ identifies itself as gcc-4.2, but has support for GNU inlining
|
||||
semantics, that can be checked for by using the __GNUC_STDC_INLINE_ and
|
||||
__GNUC_GNU_INLINE__ macro definitions. */
|
||||
#if (!defined __cplusplus || __GNUC_PREREQ (4,3) \
|
||||
|| (defined __clang__ && (defined __GNUC_STDC_INLINE__ \
|
||||
|| defined __GNUC_GNU_INLINE__)))
|
||||
# if defined __GNUC_STDC_INLINE__ || defined __cplusplus
|
||||
# define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
|
||||
# define __extern_always_inline \
|
||||
extern __always_inline __attribute__ ((__gnu_inline__))
|
||||
# else
|
||||
# define __extern_inline extern __inline
|
||||
# define __extern_always_inline extern __always_inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __extern_always_inline
|
||||
# define __fortify_function __extern_always_inline __attribute_artificial__
|
||||
#endif
|
||||
|
||||
/* GCC 4.3 and above allow passing all anonymous arguments of an
|
||||
__extern_always_inline function to some other vararg function. */
|
||||
#if __GNUC_PREREQ (4,3)
|
||||
# define __va_arg_pack() __builtin_va_arg_pack ()
|
||||
# define __va_arg_pack_len() __builtin_va_arg_pack_len ()
|
||||
#endif
|
||||
|
||||
/* It is possible to compile containing GCC extensions even if GCC is
|
||||
run in pedantic mode if the uses are carefully marked using the
|
||||
`__extension__' keyword. But this is not generally available before
|
||||
version 2.8. */
|
||||
#if !(__GNUC_PREREQ (2,8) || defined __clang__)
|
||||
# define __extension__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* __restrict is known in EGCS 1.2 and above, and in clang.
|
||||
It works also in C++ mode (outside of arrays), but only when spelled
|
||||
as '__restrict', not 'restrict'. */
|
||||
#if !(__GNUC_PREREQ (2,92) || __clang_major__ >= 3)
|
||||
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
# define __restrict restrict
|
||||
# else
|
||||
# define __restrict /* Ignore */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ISO C99 also allows to declare arrays as non-overlapping. The syntax is
|
||||
array_name[restrict]
|
||||
GCC 3.1 and clang support this.
|
||||
This syntax is not usable in C++ mode. */
|
||||
#if (__GNUC_PREREQ (3,1) || __clang_major__ >= 3) && !defined __cplusplus
|
||||
# define __restrict_arr __restrict
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define __restrict_arr /* Not supported in old GCC. */
|
||||
# else
|
||||
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
# define __restrict_arr restrict
|
||||
# else
|
||||
/* Some other non-C99 compiler. */
|
||||
# define __restrict_arr /* Not supported. */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ >= 3) || __glibc_has_builtin (__builtin_expect)
|
||||
# define __glibc_unlikely(cond) __builtin_expect ((cond), 0)
|
||||
# define __glibc_likely(cond) __builtin_expect ((cond), 1)
|
||||
#else
|
||||
# define __glibc_unlikely(cond) (cond)
|
||||
# define __glibc_likely(cond) (cond)
|
||||
#endif
|
||||
|
||||
#if (!defined _Noreturn \
|
||||
&& (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
|
||||
&& !(__GNUC_PREREQ (4,7) \
|
||||
|| (3 < __clang_major__ + (5 <= __clang_minor__))))
|
||||
# if __GNUC_PREREQ (2,8)
|
||||
# define _Noreturn __attribute__ ((__noreturn__))
|
||||
# else
|
||||
# define _Noreturn
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ (8, 0)
|
||||
/* Describes a char array whose address can safely be passed as the first
|
||||
argument to strncpy and strncat, as the char array is not necessarily
|
||||
a NUL-terminated string. */
|
||||
# define __attribute_nonstring__ __attribute__ ((__nonstring__))
|
||||
#else
|
||||
# define __attribute_nonstring__
|
||||
#endif
|
||||
|
||||
/* Undefine (also defined in libc-symbols.h). */
|
||||
#undef __attribute_copy__
|
||||
#if __GNUC_PREREQ (9, 0)
|
||||
/* Copies attributes from the declaration or type referenced by
|
||||
the argument. */
|
||||
# define __attribute_copy__(arg) __attribute__ ((__copy__ (arg)))
|
||||
#else
|
||||
# define __attribute_copy__(arg)
|
||||
#endif
|
||||
|
||||
#if (!defined _Static_assert && !defined __cplusplus \
|
||||
&& (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
|
||||
&& (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \
|
||||
|| defined __STRICT_ANSI__))
|
||||
# define _Static_assert(expr, diagnostic) \
|
||||
extern int (*__Static_assert_function (void)) \
|
||||
[!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
|
||||
#endif
|
||||
|
||||
/* Gnulib avoids including these, as they don't work on non-glibc or
|
||||
older glibc platforms. */
|
||||
#ifndef __GNULIB_CDEFS
|
||||
# include <bits/wordsize.h>
|
||||
# include <bits/long-double.h>
|
||||
#endif
|
||||
|
||||
#if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
|
||||
# ifdef __REDIRECT
|
||||
|
||||
/* Alias name defined automatically. */
|
||||
# define __LDBL_REDIR(name, proto) ... unused__ldbl_redir
|
||||
# define __LDBL_REDIR_DECL(name) \
|
||||
extern __typeof (name) name __asm (__ASMNAME ("__" #name "ieee128"));
|
||||
|
||||
/* Alias name defined automatically, with leading underscores. */
|
||||
# define __LDBL_REDIR2_DECL(name) \
|
||||
extern __typeof (__##name) __##name \
|
||||
__asm (__ASMNAME ("__" #name "ieee128"));
|
||||
|
||||
/* Alias name defined manually. */
|
||||
# define __LDBL_REDIR1(name, proto, alias) ... unused__ldbl_redir1
|
||||
# define __LDBL_REDIR1_DECL(name, alias) \
|
||||
extern __typeof (name) name __asm (__ASMNAME (#alias));
|
||||
|
||||
# define __LDBL_REDIR1_NTH(name, proto, alias) \
|
||||
__REDIRECT_NTH (name, proto, alias)
|
||||
# define __REDIRECT_NTH_LDBL(name, proto, alias) \
|
||||
__LDBL_REDIR1_NTH (name, proto, __##alias##ieee128)
|
||||
|
||||
/* Unused. */
|
||||
# define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl
|
||||
# define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth
|
||||
|
||||
# else
|
||||
_Static_assert (0, "IEEE 128-bits long double requires redirection on this platform");
|
||||
# endif
|
||||
#elif defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
|
||||
# define __LDBL_COMPAT 1
|
||||
# ifdef __REDIRECT
|
||||
# define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias)
|
||||
# define __LDBL_REDIR(name, proto) \
|
||||
__LDBL_REDIR1 (name, proto, __nldbl_##name)
|
||||
# define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias)
|
||||
# define __LDBL_REDIR_NTH(name, proto) \
|
||||
__LDBL_REDIR1_NTH (name, proto, __nldbl_##name)
|
||||
# define __LDBL_REDIR2_DECL(name) \
|
||||
extern __typeof (__##name) __##name __asm (__ASMNAME ("__nldbl___" #name));
|
||||
# define __LDBL_REDIR1_DECL(name, alias) \
|
||||
extern __typeof (name) name __asm (__ASMNAME (#alias));
|
||||
# define __LDBL_REDIR_DECL(name) \
|
||||
extern __typeof (name) name __asm (__ASMNAME ("__nldbl_" #name));
|
||||
# define __REDIRECT_LDBL(name, proto, alias) \
|
||||
__LDBL_REDIR1 (name, proto, __nldbl_##alias)
|
||||
# define __REDIRECT_NTH_LDBL(name, proto, alias) \
|
||||
__LDBL_REDIR1_NTH (name, proto, __nldbl_##alias)
|
||||
# endif
|
||||
#endif
|
||||
#if (!defined __LDBL_COMPAT && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0) \
|
||||
|| !defined __REDIRECT
|
||||
# define __LDBL_REDIR1(name, proto, alias) name proto
|
||||
# define __LDBL_REDIR(name, proto) name proto
|
||||
# define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW
|
||||
# define __LDBL_REDIR_NTH(name, proto) name proto __THROW
|
||||
# define __LDBL_REDIR2_DECL(name)
|
||||
# define __LDBL_REDIR_DECL(name)
|
||||
# ifdef __REDIRECT
|
||||
# define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias)
|
||||
# define __REDIRECT_NTH_LDBL(name, proto, alias) \
|
||||
__REDIRECT_NTH (name, proto, alias)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* __glibc_macro_warning (MESSAGE) issues warning MESSAGE. This is
|
||||
intended for use in preprocessor macros.
|
||||
|
||||
Note: MESSAGE must be a _single_ string; concatenation of string
|
||||
literals is not supported. */
|
||||
#if __GNUC_PREREQ (4,8) || __glibc_clang_prereq (3,5)
|
||||
# define __glibc_macro_warning1(message) _Pragma (#message)
|
||||
# define __glibc_macro_warning(message) \
|
||||
__glibc_macro_warning1 (GCC warning message)
|
||||
#else
|
||||
# define __glibc_macro_warning(msg)
|
||||
#endif
|
||||
|
||||
/* Generic selection (ISO C11) is a C-only feature, available in GCC
|
||||
since version 4.9. Previous versions do not provide generic
|
||||
selection, even though they might set __STDC_VERSION__ to 201112L,
|
||||
when in -std=c11 mode. Thus, we must check for !defined __GNUC__
|
||||
when testing __STDC_VERSION__ for generic selection support.
|
||||
On the other hand, Clang also defines __GNUC__, so a clang-specific
|
||||
check is required to enable the use of generic selection. */
|
||||
#if !defined __cplusplus \
|
||||
&& (__GNUC_PREREQ (4, 9) \
|
||||
|| __glibc_has_extension (c_generic_selections) \
|
||||
|| (!defined __GNUC__ && defined __STDC_VERSION__ \
|
||||
&& __STDC_VERSION__ >= 201112L))
|
||||
# define __HAVE_GENERIC_SELECTION 1
|
||||
#else
|
||||
# define __HAVE_GENERIC_SELECTION 0
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ (10, 0)
|
||||
/* Designates a 1-based positional argument ref-index of pointer type
|
||||
that can be used to access size-index elements of the pointed-to
|
||||
array according to access mode, or at least one element when
|
||||
size-index is not provided:
|
||||
access (access-mode, <ref-index> [, <size-index>]) */
|
||||
# define __attr_access(x) __attribute__ ((__access__ x))
|
||||
/* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may
|
||||
use the access attribute to get object sizes from function definition
|
||||
arguments, so we can't use them on functions we fortify. Drop the object
|
||||
size hints for such functions. */
|
||||
# if __USE_FORTIFY_LEVEL == 3
|
||||
# define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, o)))
|
||||
# else
|
||||
# define __fortified_attr_access(a, o, s) __attr_access ((a, o, s))
|
||||
# endif
|
||||
# if __GNUC_PREREQ (11, 0)
|
||||
# define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno)))
|
||||
# else
|
||||
# define __attr_access_none(argno)
|
||||
# endif
|
||||
#else
|
||||
# define __fortified_attr_access(a, o, s)
|
||||
# define __attr_access(x)
|
||||
# define __attr_access_none(argno)
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ (11, 0)
|
||||
/* Designates dealloc as a function to call to deallocate objects
|
||||
allocated by the declared function. */
|
||||
# define __attr_dealloc(dealloc, argno) \
|
||||
__attribute__ ((__malloc__ (dealloc, argno)))
|
||||
# define __attr_dealloc_free __attr_dealloc (__builtin_free, 1)
|
||||
#else
|
||||
# define __attr_dealloc(dealloc, argno)
|
||||
# define __attr_dealloc_free
|
||||
#endif
|
||||
|
||||
/* Specify that a function such as setjmp or vfork may return
|
||||
twice. */
|
||||
#if __GNUC_PREREQ (4, 1)
|
||||
# define __attribute_returns_twice__ __attribute__ ((__returns_twice__))
|
||||
#else
|
||||
# define __attribute_returns_twice__ /* Ignore. */
|
||||
#endif
|
||||
|
||||
#endif /* sys/cdefs.h */
|
|
@ -1,83 +0,0 @@
|
|||
/* cloexec.c - set or clear the close-on-exec descriptor flag
|
||||
|
||||
Copyright (C) 1991, 2004-2006, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* The code is taken from glibc/manual/llio.texi */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "cloexec.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Set the 'FD_CLOEXEC' flag of DESC if VALUE is true,
|
||||
or clear the flag if VALUE is false.
|
||||
Return 0 on success, or -1 on error with 'errno' set.
|
||||
|
||||
Note that on MingW, this function does NOT protect DESC from being
|
||||
inherited into spawned children. Instead, either use dup_cloexec
|
||||
followed by closing the original DESC, or use interfaces such as
|
||||
open or pipe2 that accept flags like O_CLOEXEC to create DESC
|
||||
non-inheritable in the first place. */
|
||||
|
||||
int
|
||||
set_cloexec_flag (int desc, bool value)
|
||||
{
|
||||
#ifdef F_SETFD
|
||||
|
||||
int flags = fcntl (desc, F_GETFD, 0);
|
||||
|
||||
if (0 <= flags)
|
||||
{
|
||||
int newflags = (value ? flags | FD_CLOEXEC : flags & ~FD_CLOEXEC);
|
||||
|
||||
if (flags == newflags
|
||||
|| fcntl (desc, F_SETFD, newflags) != -1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
#else /* !F_SETFD */
|
||||
|
||||
/* Use dup2 to reject invalid file descriptors; the cloexec flag
|
||||
will be unaffected. */
|
||||
if (desc < 0)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (dup2 (desc, desc) < 0)
|
||||
/* errno is EBADF here. */
|
||||
return -1;
|
||||
|
||||
/* There is nothing we can do on this kind of platform. Punt. */
|
||||
return 0;
|
||||
#endif /* !F_SETFD */
|
||||
}
|
||||
|
||||
|
||||
/* Duplicates a file handle FD, while marking the copy to be closed
|
||||
prior to exec or spawn. Returns -1 and sets errno if FD could not
|
||||
be duplicated. */
|
||||
|
||||
int
|
||||
dup_cloexec (int fd)
|
||||
{
|
||||
return fcntl (fd, F_DUPFD_CLOEXEC, 0);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/* cloexec.c - set or clear the close-on-exec descriptor flag
|
||||
|
||||
Copyright (C) 2004, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Set the 'FD_CLOEXEC' flag of DESC if VALUE is true,
|
||||
or clear the flag if VALUE is false.
|
||||
Return 0 on success, or -1 on error with 'errno' set.
|
||||
|
||||
Note that on MingW, this function does NOT protect DESC from being
|
||||
inherited into spawned children. Instead, either use dup_cloexec
|
||||
followed by closing the original DESC, or use interfaces such as
|
||||
open or pipe2 that accept flags like O_CLOEXEC to create DESC
|
||||
non-inheritable in the first place. */
|
||||
|
||||
int set_cloexec_flag (int desc, bool value);
|
||||
|
||||
/* Duplicates a file handle FD, while marking the copy to be closed
|
||||
prior to exec or spawn. Returns -1 and sets errno if FD could not
|
||||
be duplicated. */
|
||||
|
||||
int dup_cloexec (int fd);
|
|
@ -1,77 +0,0 @@
|
|||
/* Close a stream, with nicer error checking than fclose's.
|
||||
|
||||
Copyright (C) 1998-2002, 2004, 2006-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "close-stream.h"
|
||||
|
||||
#include <errno.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.
|
||||
|
||||
A failure with errno set to EPIPE may or may not indicate an error
|
||||
situation worth signaling to the user. See the documentation of the
|
||||
close_stdout_set_ignore_EPIPE function for details.
|
||||
|
||||
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)
|
||||
{
|
||||
const bool some_pending = (__fpending (stream) != 0);
|
||||
const bool prev_fail = (ferror (stream) != 0);
|
||||
const 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,20 +0,0 @@
|
|||
/* Close a stream, with nicer error checking than fclose's.
|
||||
|
||||
Copyright (C) 2006-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file 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 file 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int close_stream (FILE *stream);
|
|
@ -1,67 +0,0 @@
|
|||
/* Stub for copy_file_range
|
||||
Copyright 2019-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if defined __linux__ && HAVE_COPY_FILE_RANGE
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
ssize_t
|
||||
copy_file_range (int infd, off_t *pinoff,
|
||||
int outfd, off_t *poutoff,
|
||||
size_t length, unsigned int flags)
|
||||
{
|
||||
#undef copy_file_range
|
||||
|
||||
#if defined __linux__ && HAVE_COPY_FILE_RANGE
|
||||
/* The implementation of copy_file_range (which first appeared in
|
||||
Linux kernel release 4.5) had many issues before release 5.3
|
||||
<https://lwn.net/Articles/789527/>, so fail with ENOSYS for Linux
|
||||
kernels 5.2 and earlier.
|
||||
|
||||
This workaround, and the configure-time check for Linux, can be
|
||||
removed when such kernels (released March 2016 through September
|
||||
2019) are no longer a consideration. As of January 2021, the
|
||||
furthest-future planned kernel EOL is December 2024 for kernel
|
||||
release 4.19. */
|
||||
|
||||
static signed char ok;
|
||||
|
||||
if (! ok)
|
||||
{
|
||||
struct utsname name;
|
||||
uname (&name);
|
||||
char *p = name.release;
|
||||
ok = ((p[1] != '.' || '5' < p[0]
|
||||
|| (p[0] == '5' && (p[3] != '.' || '2' < p[2])))
|
||||
? 1 : -1);
|
||||
}
|
||||
|
||||
if (0 < ok)
|
||||
return copy_file_range (infd, pinoff, outfd, poutoff, length, flags);
|
||||
#endif
|
||||
|
||||
/* There is little need to emulate copy_file_range with read+write,
|
||||
since programs that use copy_file_range must fall back on
|
||||
read+write anyway. */
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/* Count the number of leading 0 bits in a word.
|
||||
|
||||
Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define COUNT_LEADING_ZEROS_INLINE _GL_EXTERN_INLINE
|
||||
#include "count-leading-zeros.h"
|
|
@ -1,136 +0,0 @@
|
|||
/* count-leading-zeros.h -- counts the number of leading 0 bits in a word.
|
||||
Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Eric Blake. */
|
||||
|
||||
#ifndef COUNT_LEADING_ZEROS_H
|
||||
#define COUNT_LEADING_ZEROS_H 1
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef COUNT_LEADING_ZEROS_INLINE
|
||||
# define COUNT_LEADING_ZEROS_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Assuming the GCC builtin is BUILTIN and the MSC builtin is MSC_BUILTIN,
|
||||
expand to code that computes the number of leading zeros of the local
|
||||
variable 'x' of type TYPE (an unsigned integer type) and return it
|
||||
from the current function. */
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
|
||||
|| (__clang_major__ >= 4)
|
||||
# define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
|
||||
return x ? BUILTIN (x) : CHAR_BIT * sizeof x;
|
||||
#elif _MSC_VER
|
||||
# pragma intrinsic (_BitScanReverse)
|
||||
# if defined _M_X64
|
||||
# pragma intrinsic (_BitScanReverse64)
|
||||
# endif
|
||||
# define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
|
||||
do \
|
||||
{ \
|
||||
unsigned long result; \
|
||||
if (MSC_BUILTIN (&result, x)) \
|
||||
return CHAR_BIT * sizeof x - 1 - result; \
|
||||
return CHAR_BIT * sizeof x; \
|
||||
} \
|
||||
while (0)
|
||||
#else
|
||||
# define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
|
||||
do \
|
||||
{ \
|
||||
int count; \
|
||||
unsigned int leading_32; \
|
||||
if (! x) \
|
||||
return CHAR_BIT * sizeof x; \
|
||||
for (count = 0; \
|
||||
(leading_32 = ((x >> (sizeof (TYPE) * CHAR_BIT - 32)) \
|
||||
& 0xffffffffU), \
|
||||
count < CHAR_BIT * sizeof x - 32 && !leading_32); \
|
||||
count += 32) \
|
||||
x = x << 31 << 1; \
|
||||
return count + count_leading_zeros_32 (leading_32); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Compute and return the number of leading zeros in X,
|
||||
where 0 < X < 2**32. */
|
||||
COUNT_LEADING_ZEROS_INLINE int
|
||||
count_leading_zeros_32 (unsigned int x)
|
||||
{
|
||||
/* <https://github.com/gibsjose/BitHacks>
|
||||
<https://www.fit.vutbr.cz/~ibarina/pub/bithacks.pdf> */
|
||||
static const char de_Bruijn_lookup[32] = {
|
||||
31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,
|
||||
23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0
|
||||
};
|
||||
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
return de_Bruijn_lookup[((x * 0x07c4acddU) & 0xffffffffU) >> 27];
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compute and return the number of leading zeros in X. */
|
||||
COUNT_LEADING_ZEROS_INLINE int
|
||||
count_leading_zeros (unsigned int x)
|
||||
{
|
||||
COUNT_LEADING_ZEROS (__builtin_clz, _BitScanReverse, unsigned int);
|
||||
}
|
||||
|
||||
/* Compute and return the number of leading zeros in X. */
|
||||
COUNT_LEADING_ZEROS_INLINE int
|
||||
count_leading_zeros_l (unsigned long int x)
|
||||
{
|
||||
COUNT_LEADING_ZEROS (__builtin_clzl, _BitScanReverse, unsigned long int);
|
||||
}
|
||||
|
||||
/* Compute and return the number of leading zeros in X. */
|
||||
COUNT_LEADING_ZEROS_INLINE int
|
||||
count_leading_zeros_ll (unsigned long long int x)
|
||||
{
|
||||
#if (defined _MSC_VER && !defined __clang__) && !defined _M_X64
|
||||
/* 32-bit MSVC does not have _BitScanReverse64, only _BitScanReverse. */
|
||||
unsigned long result;
|
||||
if (_BitScanReverse (&result, (unsigned long) (x >> 32)))
|
||||
return CHAR_BIT * sizeof x - 1 - 32 - result;
|
||||
if (_BitScanReverse (&result, (unsigned long) x))
|
||||
return CHAR_BIT * sizeof x - 1 - result;
|
||||
return CHAR_BIT * sizeof x;
|
||||
#else
|
||||
COUNT_LEADING_ZEROS (__builtin_clzll, _BitScanReverse64,
|
||||
unsigned long long int);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif /* COUNT_LEADING_ZEROS_H */
|
|
@ -1,25 +0,0 @@
|
|||
/* Count the number of 1-bits in a word.
|
||||
|
||||
Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define COUNT_ONE_BITS_INLINE _GL_EXTERN_INLINE
|
||||
#include "count-one-bits.h"
|
||||
|
||||
#if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64)
|
||||
int popcount_support = -1;
|
||||
#endif
|
|
@ -1,164 +0,0 @@
|
|||
/* count-one-bits.h -- counts the number of 1-bits in a word.
|
||||
Copyright (C) 2007-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Ben Pfaff. */
|
||||
|
||||
#ifndef COUNT_ONE_BITS_H
|
||||
#define COUNT_ONE_BITS_H 1
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef COUNT_ONE_BITS_INLINE
|
||||
# define COUNT_ONE_BITS_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Assuming the GCC builtin is GCC_BUILTIN and the MSC builtin is MSC_BUILTIN,
|
||||
expand to code that computes the number of 1-bits of the local
|
||||
variable 'x' of type TYPE (an unsigned integer type) and return it
|
||||
from the current function. */
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
|
||||
|| (__clang_major__ >= 4)
|
||||
# define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \
|
||||
return GCC_BUILTIN (x)
|
||||
#else
|
||||
|
||||
/* Compute and return the number of 1-bits set in the least
|
||||
significant 32 bits of X. */
|
||||
COUNT_ONE_BITS_INLINE int
|
||||
count_one_bits_32 (unsigned int x)
|
||||
{
|
||||
x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U);
|
||||
x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U);
|
||||
x = (x >> 16) + (x & 0xffff);
|
||||
x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f);
|
||||
return (x >> 8) + (x & 0x00ff);
|
||||
}
|
||||
|
||||
/* Expand to code that computes the number of 1-bits of the local
|
||||
variable 'x' of type TYPE (an unsigned integer type) and return it
|
||||
from the current function. */
|
||||
# define COUNT_ONE_BITS_GENERIC(TYPE) \
|
||||
do \
|
||||
{ \
|
||||
int count = 0; \
|
||||
int bits; \
|
||||
for (bits = 0; bits < sizeof (TYPE) * CHAR_BIT; bits += 32) \
|
||||
{ \
|
||||
count += count_one_bits_32 (x); \
|
||||
x = x >> 31 >> 1; \
|
||||
} \
|
||||
return count; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
# if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64)
|
||||
|
||||
/* While gcc falls back to its own generic code if the machine
|
||||
on which it's running doesn't support popcount, with Microsoft's
|
||||
compiler we need to detect and fallback ourselves. */
|
||||
|
||||
# if 0
|
||||
# include <intrin.h>
|
||||
# else
|
||||
/* Don't pollute the namespace with too many MSVC intrinsics. */
|
||||
# pragma intrinsic (__cpuid)
|
||||
# pragma intrinsic (__popcnt)
|
||||
# if defined _M_X64
|
||||
# pragma intrinsic (__popcnt64)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined _M_X64
|
||||
static inline __popcnt64 (unsigned long long x)
|
||||
{
|
||||
return __popcnt ((unsigned int) (x >> 32)) + __popcnt ((unsigned int) x);
|
||||
}
|
||||
# endif
|
||||
|
||||
/* Return nonzero if popcount is supported. */
|
||||
|
||||
/* 1 if supported, 0 if not supported, -1 if unknown. */
|
||||
extern int popcount_support;
|
||||
|
||||
COUNT_ONE_BITS_INLINE int
|
||||
popcount_supported (void)
|
||||
{
|
||||
if (popcount_support < 0)
|
||||
{
|
||||
/* Do as described in
|
||||
<https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64> */
|
||||
int cpu_info[4];
|
||||
__cpuid (cpu_info, 1);
|
||||
popcount_support = (cpu_info[2] >> 23) & 1;
|
||||
}
|
||||
return popcount_support;
|
||||
}
|
||||
|
||||
# define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \
|
||||
do \
|
||||
{ \
|
||||
if (popcount_supported ()) \
|
||||
return MSC_BUILTIN (x); \
|
||||
else \
|
||||
COUNT_ONE_BITS_GENERIC (TYPE); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
# else
|
||||
|
||||
# define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \
|
||||
COUNT_ONE_BITS_GENERIC (TYPE)
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Compute and return the number of 1-bits set in X. */
|
||||
COUNT_ONE_BITS_INLINE int
|
||||
count_one_bits (unsigned int x)
|
||||
{
|
||||
COUNT_ONE_BITS (__builtin_popcount, __popcnt, unsigned int);
|
||||
}
|
||||
|
||||
/* Compute and return the number of 1-bits set in X. */
|
||||
COUNT_ONE_BITS_INLINE int
|
||||
count_one_bits_l (unsigned long int x)
|
||||
{
|
||||
COUNT_ONE_BITS (__builtin_popcountl, __popcnt, unsigned long int);
|
||||
}
|
||||
|
||||
/* Compute and return the number of 1-bits set in X. */
|
||||
COUNT_ONE_BITS_INLINE int
|
||||
count_one_bits_ll (unsigned long long int x)
|
||||
{
|
||||
COUNT_ONE_BITS (__builtin_popcountll, __popcnt64, unsigned long long int);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif /* COUNT_ONE_BITS_H */
|
|
@ -1,21 +0,0 @@
|
|||
/* Count the number of trailing 0 bits in a word.
|
||||
|
||||
Copyright 2013-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define COUNT_TRAILING_ZEROS_INLINE _GL_EXTERN_INLINE
|
||||
#include "count-trailing-zeros.h"
|
|
@ -1,126 +0,0 @@
|
|||
/* count-trailing-zeros.h -- counts the number of trailing 0 bits in a word.
|
||||
Copyright 2013-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert. */
|
||||
|
||||
#ifndef COUNT_TRAILING_ZEROS_H
|
||||
#define COUNT_TRAILING_ZEROS_H 1
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef COUNT_TRAILING_ZEROS_INLINE
|
||||
# define COUNT_TRAILING_ZEROS_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Assuming the GCC builtin is BUILTIN and the MSC builtin is MSC_BUILTIN,
|
||||
expand to code that computes the number of trailing zeros of the local
|
||||
variable 'x' of type TYPE (an unsigned integer type) and return it
|
||||
from the current function. */
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
|
||||
|| (__clang_major__ >= 4)
|
||||
# define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
|
||||
return x ? BUILTIN (x) : CHAR_BIT * sizeof x;
|
||||
#elif _MSC_VER
|
||||
# pragma intrinsic (_BitScanForward)
|
||||
# if defined _M_X64
|
||||
# pragma intrinsic (_BitScanForward64)
|
||||
# endif
|
||||
# define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
|
||||
do \
|
||||
{ \
|
||||
unsigned long result; \
|
||||
return MSC_BUILTIN (&result, x) ? result : CHAR_BIT * sizeof x; \
|
||||
} \
|
||||
while (0)
|
||||
#else
|
||||
# define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
|
||||
do \
|
||||
{ \
|
||||
int count = 0; \
|
||||
if (! x) \
|
||||
return CHAR_BIT * sizeof x; \
|
||||
for (count = 0; \
|
||||
(count < CHAR_BIT * sizeof x - 32 \
|
||||
&& ! (x & 0xffffffffU)); \
|
||||
count += 32) \
|
||||
x = x >> 31 >> 1; \
|
||||
return count + count_trailing_zeros_32 (x); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Compute and return the number of trailing zeros in the least
|
||||
significant 32 bits of X. One of these bits must be nonzero. */
|
||||
COUNT_TRAILING_ZEROS_INLINE int
|
||||
count_trailing_zeros_32 (unsigned int x)
|
||||
{
|
||||
/* <https://github.com/gibsjose/BitHacks>
|
||||
<https://www.fit.vutbr.cz/~ibarina/pub/bithacks.pdf> */
|
||||
static const char de_Bruijn_lookup[32] = {
|
||||
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
||||
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
|
||||
};
|
||||
return de_Bruijn_lookup[(((x & -x) * 0x077cb531U) & 0xffffffffU) >> 27];
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compute and return the number of trailing zeros in X. */
|
||||
COUNT_TRAILING_ZEROS_INLINE int
|
||||
count_trailing_zeros (unsigned int x)
|
||||
{
|
||||
COUNT_TRAILING_ZEROS (__builtin_ctz, _BitScanForward, unsigned int);
|
||||
}
|
||||
|
||||
/* Compute and return the number of trailing zeros in X. */
|
||||
COUNT_TRAILING_ZEROS_INLINE int
|
||||
count_trailing_zeros_l (unsigned long int x)
|
||||
{
|
||||
COUNT_TRAILING_ZEROS (__builtin_ctzl, _BitScanForward, unsigned long int);
|
||||
}
|
||||
|
||||
/* Compute and return the number of trailing zeros in X. */
|
||||
COUNT_TRAILING_ZEROS_INLINE int
|
||||
count_trailing_zeros_ll (unsigned long long int x)
|
||||
{
|
||||
#if (defined _MSC_VER && !defined __clang__) && !defined _M_X64
|
||||
/* 32-bit MSVC does not have _BitScanForward64, only _BitScanForward. */
|
||||
unsigned long result;
|
||||
if (_BitScanForward (&result, (unsigned long) x))
|
||||
return result;
|
||||
if (_BitScanForward (&result, (unsigned long) (x >> 32)))
|
||||
return result + 32;
|
||||
return CHAR_BIT * sizeof x;
|
||||
#else
|
||||
COUNT_TRAILING_ZEROS (__builtin_ctzll, _BitScanForward64,
|
||||
unsigned long long int);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif
|
|
@ -1,568 +0,0 @@
|
|||
/* Analyze differences between two vectors.
|
||||
|
||||
Copyright (C) 1988-1989, 1992-1995, 2001-2004, 2006-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* The basic idea is to consider two vectors as similar if, when
|
||||
transforming the first vector into the second vector through a
|
||||
sequence of edits (inserts and deletes of one element each),
|
||||
this sequence is short - or equivalently, if the ordered list
|
||||
of elements that are untouched by these edits is long. For a
|
||||
good introduction to the subject, read about the "Levenshtein
|
||||
distance" in Wikipedia.
|
||||
|
||||
The basic algorithm is described in:
|
||||
"An O(ND) Difference Algorithm and its Variations", Eugene W. Myers,
|
||||
Algorithmica Vol. 1, 1986, pp. 251-266,
|
||||
<https://doi.org/10.1007/BF01840446>.
|
||||
See especially section 4.2, which describes the variation used below.
|
||||
|
||||
The basic algorithm was independently discovered as described in:
|
||||
"Algorithms for Approximate String Matching", Esko Ukkonen,
|
||||
Information and Control Vol. 64, 1985, pp. 100-118,
|
||||
<https://doi.org/10.1016/S0019-9958(85)80046-2>.
|
||||
|
||||
Unless the 'find_minimal' flag is set, this code uses the TOO_EXPENSIVE
|
||||
heuristic, by Paul Eggert, to limit the cost to O(N**1.5 log N)
|
||||
at the price of producing suboptimal output for large inputs with
|
||||
many differences. */
|
||||
|
||||
/* Before including this file, you need to define:
|
||||
ELEMENT The element type of the vectors being compared.
|
||||
EQUAL A two-argument macro that tests two elements for
|
||||
equality.
|
||||
OFFSET A signed integer type sufficient to hold the
|
||||
difference between two indices. Usually
|
||||
something like ptrdiff_t.
|
||||
EXTRA_CONTEXT_FIELDS Declarations of fields for 'struct context'.
|
||||
NOTE_DELETE(ctxt, xoff) Record the removal of the object xvec[xoff].
|
||||
NOTE_INSERT(ctxt, yoff) Record the insertion of the object yvec[yoff].
|
||||
NOTE_ORDERED (Optional) A boolean expression saying that
|
||||
NOTE_DELETE and NOTE_INSERT calls must be
|
||||
issued in offset order.
|
||||
EARLY_ABORT(ctxt) (Optional) A boolean expression that triggers an
|
||||
early abort of the computation.
|
||||
USE_HEURISTIC (Optional) Define if you want to support the
|
||||
heuristic for large vectors.
|
||||
|
||||
It is also possible to use this file with abstract arrays. In this case,
|
||||
xvec and yvec are not represented in memory. They only exist conceptually.
|
||||
In this case, the list of defines above is amended as follows:
|
||||
ELEMENT Undefined.
|
||||
EQUAL Undefined.
|
||||
XVECREF_YVECREF_EQUAL(ctxt, xoff, yoff)
|
||||
A three-argument macro: References xvec[xoff] and
|
||||
yvec[yoff] and tests these elements for equality.
|
||||
|
||||
Before including this file, you also need to include:
|
||||
#include <limits.h>
|
||||
#include "minmax.h"
|
||||
*/
|
||||
|
||||
/* Maximum value of type OFFSET. */
|
||||
#define OFFSET_MAX \
|
||||
((((OFFSET)1 << (sizeof (OFFSET) * CHAR_BIT - 2)) - 1) * 2 + 1)
|
||||
|
||||
/* Default to no early abort. */
|
||||
#ifndef EARLY_ABORT
|
||||
# define EARLY_ABORT(ctxt) false
|
||||
#endif
|
||||
|
||||
#ifndef NOTE_ORDERED
|
||||
# define NOTE_ORDERED false
|
||||
#endif
|
||||
|
||||
/* Use this to suppress gcc's "...may be used before initialized" warnings.
|
||||
Beware: The Code argument must not contain commas. */
|
||||
#ifndef IF_LINT
|
||||
# if defined GCC_LINT || defined lint
|
||||
# define IF_LINT(Code) Code
|
||||
# else
|
||||
# define IF_LINT(Code) /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Context of comparison operation.
|
||||
*/
|
||||
struct context
|
||||
{
|
||||
#ifdef ELEMENT
|
||||
/* Vectors being compared. */
|
||||
ELEMENT const *xvec;
|
||||
ELEMENT const *yvec;
|
||||
#endif
|
||||
|
||||
/* Extra fields. */
|
||||
EXTRA_CONTEXT_FIELDS
|
||||
|
||||
/* Vector, indexed by diagonal, containing 1 + the X coordinate of the point
|
||||
furthest along the given diagonal in the forward search of the edit
|
||||
matrix. */
|
||||
OFFSET *fdiag;
|
||||
|
||||
/* Vector, indexed by diagonal, containing the X coordinate of the point
|
||||
furthest along the given diagonal in the backward search of the edit
|
||||
matrix. */
|
||||
OFFSET *bdiag;
|
||||
|
||||
#ifdef USE_HEURISTIC
|
||||
/* This corresponds to the diff --speed-large-files flag. With this
|
||||
heuristic, for vectors with a constant small density of changes,
|
||||
the algorithm is linear in the vector size. */
|
||||
bool heuristic;
|
||||
#endif
|
||||
|
||||
/* Edit scripts longer than this are too expensive to compute. */
|
||||
OFFSET too_expensive;
|
||||
|
||||
/* Snakes bigger than this are considered "big". */
|
||||
#define SNAKE_LIMIT 20
|
||||
};
|
||||
|
||||
struct partition
|
||||
{
|
||||
/* Midpoints of this partition. */
|
||||
OFFSET xmid;
|
||||
OFFSET ymid;
|
||||
|
||||
/* True if low half will be analyzed minimally. */
|
||||
bool lo_minimal;
|
||||
|
||||
/* Likewise for high half. */
|
||||
bool hi_minimal;
|
||||
};
|
||||
|
||||
|
||||
/* Find the midpoint of the shortest edit script for a specified portion
|
||||
of the two vectors.
|
||||
|
||||
Scan from the beginnings of the vectors, and simultaneously from the ends,
|
||||
doing a breadth-first search through the space of edit-sequence.
|
||||
When the two searches meet, we have found the midpoint of the shortest
|
||||
edit sequence.
|
||||
|
||||
If FIND_MINIMAL is true, find the minimal edit script regardless of
|
||||
expense. Otherwise, if the search is too expensive, use heuristics to
|
||||
stop the search and report a suboptimal answer.
|
||||
|
||||
Set PART->(xmid,ymid) to the midpoint (XMID,YMID). The diagonal number
|
||||
XMID - YMID equals the number of inserted elements minus the number
|
||||
of deleted elements (counting only elements before the midpoint).
|
||||
|
||||
Set PART->lo_minimal to true iff the minimal edit script for the
|
||||
left half of the partition is known; similarly for PART->hi_minimal.
|
||||
|
||||
This function assumes that the first elements of the specified portions
|
||||
of the two vectors do not match, and likewise that the last elements do not
|
||||
match. The caller must trim matching elements from the beginning and end
|
||||
of the portions it is going to specify.
|
||||
|
||||
If we return the "wrong" partitions, the worst this can do is cause
|
||||
suboptimal diff output. It cannot cause incorrect diff output. */
|
||||
|
||||
static void
|
||||
diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal,
|
||||
struct partition *part, struct context *ctxt)
|
||||
{
|
||||
OFFSET *const fd = ctxt->fdiag; /* Give the compiler a chance. */
|
||||
OFFSET *const bd = ctxt->bdiag; /* Additional help for the compiler. */
|
||||
#ifdef ELEMENT
|
||||
ELEMENT const *const xv = ctxt->xvec; /* Still more help for the compiler. */
|
||||
ELEMENT const *const yv = ctxt->yvec; /* And more and more . . . */
|
||||
#define XREF_YREF_EQUAL(x,y) EQUAL (xv[x], yv[y])
|
||||
#else
|
||||
#define XREF_YREF_EQUAL(x,y) XVECREF_YVECREF_EQUAL (ctxt, x, y)
|
||||
#endif
|
||||
const OFFSET dmin = xoff - ylim; /* Minimum valid diagonal. */
|
||||
const OFFSET dmax = xlim - yoff; /* Maximum valid diagonal. */
|
||||
const OFFSET fmid = xoff - yoff; /* Center diagonal of top-down search. */
|
||||
const OFFSET bmid = xlim - ylim; /* Center diagonal of bottom-up search. */
|
||||
OFFSET fmin = fmid;
|
||||
OFFSET fmax = fmid; /* Limits of top-down search. */
|
||||
OFFSET bmin = bmid;
|
||||
OFFSET bmax = bmid; /* Limits of bottom-up search. */
|
||||
OFFSET c; /* Cost. */
|
||||
bool odd = (fmid - bmid) & 1; /* True if southeast corner is on an odd
|
||||
diagonal with respect to the northwest. */
|
||||
|
||||
fd[fmid] = xoff;
|
||||
bd[bmid] = xlim;
|
||||
|
||||
for (c = 1;; ++c)
|
||||
{
|
||||
OFFSET d; /* Active diagonal. */
|
||||
bool big_snake = false;
|
||||
|
||||
/* Extend the top-down search by an edit step in each diagonal. */
|
||||
if (fmin > dmin)
|
||||
fd[--fmin - 1] = -1;
|
||||
else
|
||||
++fmin;
|
||||
if (fmax < dmax)
|
||||
fd[++fmax + 1] = -1;
|
||||
else
|
||||
--fmax;
|
||||
for (d = fmax; d >= fmin; d -= 2)
|
||||
{
|
||||
OFFSET x;
|
||||
OFFSET y;
|
||||
OFFSET tlo = fd[d - 1];
|
||||
OFFSET thi = fd[d + 1];
|
||||
OFFSET x0 = tlo < thi ? thi : tlo + 1;
|
||||
|
||||
for (x = x0, y = x0 - d;
|
||||
x < xlim && y < ylim && XREF_YREF_EQUAL (x, y);
|
||||
x++, y++)
|
||||
continue;
|
||||
if (x - x0 > SNAKE_LIMIT)
|
||||
big_snake = true;
|
||||
fd[d] = x;
|
||||
if (odd && bmin <= d && d <= bmax && bd[d] <= x)
|
||||
{
|
||||
part->xmid = x;
|
||||
part->ymid = y;
|
||||
part->lo_minimal = part->hi_minimal = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Similarly extend the bottom-up search. */
|
||||
if (bmin > dmin)
|
||||
bd[--bmin - 1] = OFFSET_MAX;
|
||||
else
|
||||
++bmin;
|
||||
if (bmax < dmax)
|
||||
bd[++bmax + 1] = OFFSET_MAX;
|
||||
else
|
||||
--bmax;
|
||||
for (d = bmax; d >= bmin; d -= 2)
|
||||
{
|
||||
OFFSET x;
|
||||
OFFSET y;
|
||||
OFFSET tlo = bd[d - 1];
|
||||
OFFSET thi = bd[d + 1];
|
||||
OFFSET x0 = tlo < thi ? tlo : thi - 1;
|
||||
|
||||
for (x = x0, y = x0 - d;
|
||||
xoff < x && yoff < y && XREF_YREF_EQUAL (x - 1, y - 1);
|
||||
x--, y--)
|
||||
continue;
|
||||
if (x0 - x > SNAKE_LIMIT)
|
||||
big_snake = true;
|
||||
bd[d] = x;
|
||||
if (!odd && fmin <= d && d <= fmax && x <= fd[d])
|
||||
{
|
||||
part->xmid = x;
|
||||
part->ymid = y;
|
||||
part->lo_minimal = part->hi_minimal = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (find_minimal)
|
||||
continue;
|
||||
|
||||
#ifdef USE_HEURISTIC
|
||||
bool heuristic = ctxt->heuristic;
|
||||
#else
|
||||
bool heuristic = false;
|
||||
#endif
|
||||
|
||||
/* Heuristic: check occasionally for a diagonal that has made lots
|
||||
of progress compared with the edit distance. If we have any
|
||||
such, find the one that has made the most progress and return it
|
||||
as if it had succeeded.
|
||||
|
||||
With this heuristic, for vectors with a constant small density
|
||||
of changes, the algorithm is linear in the vector size. */
|
||||
|
||||
if (200 < c && big_snake && heuristic)
|
||||
{
|
||||
{
|
||||
OFFSET best = 0;
|
||||
|
||||
for (d = fmax; d >= fmin; d -= 2)
|
||||
{
|
||||
OFFSET dd = d - fmid;
|
||||
OFFSET x = fd[d];
|
||||
OFFSET y = x - d;
|
||||
OFFSET v = (x - xoff) * 2 - dd;
|
||||
|
||||
if (v > 12 * (c + (dd < 0 ? -dd : dd)))
|
||||
{
|
||||
if (v > best
|
||||
&& xoff + SNAKE_LIMIT <= x && x < xlim
|
||||
&& yoff + SNAKE_LIMIT <= y && y < ylim)
|
||||
{
|
||||
/* We have a good enough best diagonal; now insist
|
||||
that it end with a significant snake. */
|
||||
int k;
|
||||
|
||||
for (k = 1; XREF_YREF_EQUAL (x - k, y - k); k++)
|
||||
if (k == SNAKE_LIMIT)
|
||||
{
|
||||
best = v;
|
||||
part->xmid = x;
|
||||
part->ymid = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best > 0)
|
||||
{
|
||||
part->lo_minimal = true;
|
||||
part->hi_minimal = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
OFFSET best = 0;
|
||||
|
||||
for (d = bmax; d >= bmin; d -= 2)
|
||||
{
|
||||
OFFSET dd = d - bmid;
|
||||
OFFSET x = bd[d];
|
||||
OFFSET y = x - d;
|
||||
OFFSET v = (xlim - x) * 2 + dd;
|
||||
|
||||
if (v > 12 * (c + (dd < 0 ? -dd : dd)))
|
||||
{
|
||||
if (v > best
|
||||
&& xoff < x && x <= xlim - SNAKE_LIMIT
|
||||
&& yoff < y && y <= ylim - SNAKE_LIMIT)
|
||||
{
|
||||
/* We have a good enough best diagonal; now insist
|
||||
that it end with a significant snake. */
|
||||
int k;
|
||||
|
||||
for (k = 0; XREF_YREF_EQUAL (x + k, y + k); k++)
|
||||
if (k == SNAKE_LIMIT - 1)
|
||||
{
|
||||
best = v;
|
||||
part->xmid = x;
|
||||
part->ymid = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best > 0)
|
||||
{
|
||||
part->lo_minimal = false;
|
||||
part->hi_minimal = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Heuristic: if we've gone well beyond the call of duty, give up
|
||||
and report halfway between our best results so far. */
|
||||
if (c >= ctxt->too_expensive)
|
||||
{
|
||||
OFFSET fxybest;
|
||||
OFFSET fxbest IF_LINT (= 0);
|
||||
OFFSET bxybest;
|
||||
OFFSET bxbest IF_LINT (= 0);
|
||||
|
||||
/* Find forward diagonal that maximizes X + Y. */
|
||||
fxybest = -1;
|
||||
for (d = fmax; d >= fmin; d -= 2)
|
||||
{
|
||||
OFFSET x = MIN (fd[d], xlim);
|
||||
OFFSET y = x - d;
|
||||
if (ylim < y)
|
||||
{
|
||||
x = ylim + d;
|
||||
y = ylim;
|
||||
}
|
||||
if (fxybest < x + y)
|
||||
{
|
||||
fxybest = x + y;
|
||||
fxbest = x;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find backward diagonal that minimizes X + Y. */
|
||||
bxybest = OFFSET_MAX;
|
||||
for (d = bmax; d >= bmin; d -= 2)
|
||||
{
|
||||
OFFSET x = MAX (xoff, bd[d]);
|
||||
OFFSET y = x - d;
|
||||
if (y < yoff)
|
||||
{
|
||||
x = yoff + d;
|
||||
y = yoff;
|
||||
}
|
||||
if (x + y < bxybest)
|
||||
{
|
||||
bxybest = x + y;
|
||||
bxbest = x;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the better of the two diagonals. */
|
||||
if ((xlim + ylim) - bxybest < fxybest - (xoff + yoff))
|
||||
{
|
||||
part->xmid = fxbest;
|
||||
part->ymid = fxybest - fxbest;
|
||||
part->lo_minimal = true;
|
||||
part->hi_minimal = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
part->xmid = bxbest;
|
||||
part->ymid = bxybest - bxbest;
|
||||
part->lo_minimal = false;
|
||||
part->hi_minimal = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
#undef XREF_YREF_EQUAL
|
||||
}
|
||||
|
||||
|
||||
/* Compare in detail contiguous subsequences of the two vectors
|
||||
which are known, as a whole, to match each other.
|
||||
|
||||
The subsequence of vector 0 is [XOFF, XLIM) and likewise for vector 1.
|
||||
|
||||
Note that XLIM, YLIM are exclusive bounds. All indices into the vectors
|
||||
are origin-0.
|
||||
|
||||
If FIND_MINIMAL, find a minimal difference no matter how
|
||||
expensive it is.
|
||||
|
||||
The results are recorded by invoking NOTE_DELETE and NOTE_INSERT.
|
||||
|
||||
Return false if terminated normally, or true if terminated through early
|
||||
abort. */
|
||||
|
||||
static bool
|
||||
compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim,
|
||||
bool find_minimal, struct context *ctxt)
|
||||
{
|
||||
#ifdef ELEMENT
|
||||
ELEMENT const *xv = ctxt->xvec; /* Help the compiler. */
|
||||
ELEMENT const *yv = ctxt->yvec;
|
||||
#define XREF_YREF_EQUAL(x,y) EQUAL (xv[x], yv[y])
|
||||
#else
|
||||
#define XREF_YREF_EQUAL(x,y) XVECREF_YVECREF_EQUAL (ctxt, x, y)
|
||||
#endif
|
||||
|
||||
while (true)
|
||||
{
|
||||
/* Slide down the bottom initial diagonal. */
|
||||
while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xoff, yoff))
|
||||
{
|
||||
xoff++;
|
||||
yoff++;
|
||||
}
|
||||
|
||||
/* Slide up the top initial diagonal. */
|
||||
while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xlim - 1, ylim - 1))
|
||||
{
|
||||
xlim--;
|
||||
ylim--;
|
||||
}
|
||||
|
||||
/* Handle simple cases. */
|
||||
if (xoff == xlim)
|
||||
{
|
||||
while (yoff < ylim)
|
||||
{
|
||||
NOTE_INSERT (ctxt, yoff);
|
||||
if (EARLY_ABORT (ctxt))
|
||||
return true;
|
||||
yoff++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (yoff == ylim)
|
||||
{
|
||||
while (xoff < xlim)
|
||||
{
|
||||
NOTE_DELETE (ctxt, xoff);
|
||||
if (EARLY_ABORT (ctxt))
|
||||
return true;
|
||||
xoff++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
struct partition part;
|
||||
|
||||
/* Find a point of correspondence in the middle of the vectors. */
|
||||
diag (xoff, xlim, yoff, ylim, find_minimal, &part, ctxt);
|
||||
|
||||
/* Use the partitions to split this problem into subproblems. */
|
||||
OFFSET xoff1, xlim1, yoff1, ylim1, xoff2, xlim2, yoff2, ylim2;
|
||||
bool find_minimal1, find_minimal2;
|
||||
if (!NOTE_ORDERED
|
||||
&& ((xlim + ylim) - (part.xmid + part.ymid)
|
||||
< (part.xmid + part.ymid) - (xoff + yoff)))
|
||||
{
|
||||
/* The second problem is smaller and the caller doesn't
|
||||
care about order, so do the second problem first to
|
||||
lessen recursion. */
|
||||
xoff1 = part.xmid; xlim1 = xlim;
|
||||
yoff1 = part.ymid; ylim1 = ylim;
|
||||
find_minimal1 = part.hi_minimal;
|
||||
|
||||
xoff2 = xoff; xlim2 = part.xmid;
|
||||
yoff2 = yoff; ylim2 = part.ymid;
|
||||
find_minimal2 = part.lo_minimal;
|
||||
}
|
||||
else
|
||||
{
|
||||
xoff1 = xoff; xlim1 = part.xmid;
|
||||
yoff1 = yoff; ylim1 = part.ymid;
|
||||
find_minimal1 = part.lo_minimal;
|
||||
|
||||
xoff2 = part.xmid; xlim2 = xlim;
|
||||
yoff2 = part.ymid; ylim2 = ylim;
|
||||
find_minimal2 = part.hi_minimal;
|
||||
}
|
||||
|
||||
/* Recurse to do one subproblem. */
|
||||
bool early = compareseq (xoff1, xlim1, yoff1, ylim1, find_minimal1, ctxt);
|
||||
if (early)
|
||||
return early;
|
||||
|
||||
/* Iterate to do the other subproblem. */
|
||||
xoff = xoff2; xlim = xlim2;
|
||||
yoff = yoff2; ylim = ylim2;
|
||||
find_minimal = find_minimal2;
|
||||
}
|
||||
|
||||
return false;
|
||||
#undef XREF_YREF_EQUAL
|
||||
}
|
||||
|
||||
#undef ELEMENT
|
||||
#undef EQUAL
|
||||
#undef OFFSET
|
||||
#undef EXTRA_CONTEXT_FIELDS
|
||||
#undef NOTE_DELETE
|
||||
#undef NOTE_INSERT
|
||||
#undef EARLY_ABORT
|
||||
#undef USE_HEURISTIC
|
||||
#undef XVECREF_YVECREF_EQUAL
|
||||
#undef OFFSET_MAX
|
|
@ -1,321 +0,0 @@
|
|||
/* A GNU-like <dirent.h>.
|
||||
Copyright (C) 2006-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_DIRENT_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#if @HAVE_DIRENT_H@
|
||||
# @INCLUDE_NEXT@ @NEXT_DIRENT_H@
|
||||
#endif
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_DIRENT_H
|
||||
#define _@GUARD_PREFIX@_DIRENT_H
|
||||
|
||||
/* Get ino_t. Needed on some systems, including glibc 2.8. */
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !@HAVE_DIRENT_H@
|
||||
/* Define types DIR and 'struct dirent'. */
|
||||
# if !GNULIB_defined_struct_dirent
|
||||
struct dirent
|
||||
{
|
||||
char d_type;
|
||||
char d_name[1];
|
||||
};
|
||||
/* Possible values for 'd_type'. */
|
||||
# define DT_UNKNOWN 0
|
||||
# define DT_FIFO 1 /* FIFO */
|
||||
# define DT_CHR 2 /* character device */
|
||||
# define DT_DIR 4 /* directory */
|
||||
# define DT_BLK 6 /* block device */
|
||||
# define DT_REG 8 /* regular file */
|
||||
# define DT_LNK 10 /* symbolic link */
|
||||
# define DT_SOCK 12 /* socket */
|
||||
# define DT_WHT 14 /* whiteout */
|
||||
typedef struct gl_directory DIR;
|
||||
# define GNULIB_defined_struct_dirent 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
|
||||
that can be freed by passing them as the Ith argument to the
|
||||
function F. */
|
||||
#ifndef _GL_ATTRIBUTE_DEALLOC
|
||||
# if __GNUC__ >= 11
|
||||
# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
|
||||
# else
|
||||
# define _GL_ATTRIBUTE_DEALLOC(f, i)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
|
||||
allocated memory. */
|
||||
/* Applies to: functions. */
|
||||
#ifndef _GL_ATTRIBUTE_MALLOC
|
||||
# if __GNUC__ >= 3 || defined __clang__
|
||||
# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
|
||||
# else
|
||||
# define _GL_ATTRIBUTE_MALLOC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The __attribute__ feature is available in gcc versions 2.5 and later.
|
||||
The attribute __pure__ was added in gcc 2.96. */
|
||||
#ifndef _GL_ATTRIBUTE_PURE
|
||||
# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__
|
||||
# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
|
||||
# else
|
||||
# define _GL_ATTRIBUTE_PURE /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
||||
|
||||
/* The definition of _GL_ARG_NONNULL is copied here. */
|
||||
|
||||
/* The definition of _GL_WARN_ON_USE is copied here. */
|
||||
|
||||
|
||||
/* Declare overridden functions. */
|
||||
|
||||
#if @GNULIB_CLOSEDIR@
|
||||
# if @REPLACE_CLOSEDIR@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef closedir
|
||||
# define closedir rpl_closedir
|
||||
# define GNULIB_defined_closedir 1
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
|
||||
_GL_CXXALIAS_RPL (closedir, int, (DIR *dirp));
|
||||
# else
|
||||
# if !@HAVE_CLOSEDIR@
|
||||
_GL_FUNCDECL_SYS (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (closedir, int, (DIR *dirp));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (closedir);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef closedir
|
||||
# if HAVE_RAW_DECL_CLOSEDIR
|
||||
_GL_WARN_ON_USE (closedir, "closedir is not portable - "
|
||||
"use gnulib module closedir for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_OPENDIR@
|
||||
# if @REPLACE_OPENDIR@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef opendir
|
||||
# define opendir rpl_opendir
|
||||
# define GNULIB_defined_opendir 1
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (opendir, DIR *,
|
||||
(const char *dir_name)
|
||||
_GL_ARG_NONNULL ((1))
|
||||
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
|
||||
_GL_CXXALIAS_RPL (opendir, DIR *, (const char *dir_name));
|
||||
# else
|
||||
# if !@HAVE_OPENDIR@ || __GNUC__ >= 11
|
||||
_GL_FUNCDECL_SYS (opendir, DIR *,
|
||||
(const char *dir_name)
|
||||
_GL_ARG_NONNULL ((1))
|
||||
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (opendir, DIR *, (const char *dir_name));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (opendir);
|
||||
#else
|
||||
# if @GNULIB_CLOSEDIR@ && __GNUC__ >= 11 && !defined opendir
|
||||
/* For -Wmismatched-dealloc: Associate opendir with closedir or
|
||||
rpl_closedir. */
|
||||
_GL_FUNCDECL_SYS (opendir, DIR *,
|
||||
(const char *dir_name)
|
||||
_GL_ARG_NONNULL ((1))
|
||||
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
|
||||
# endif
|
||||
# if defined GNULIB_POSIXCHECK
|
||||
# undef opendir
|
||||
# if HAVE_RAW_DECL_OPENDIR
|
||||
_GL_WARN_ON_USE (opendir, "opendir is not portable - "
|
||||
"use gnulib module opendir for portability");
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_READDIR@
|
||||
# if !@HAVE_READDIR@
|
||||
_GL_FUNCDECL_SYS (readdir, struct dirent *, (DIR *dirp) _GL_ARG_NONNULL ((1)));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (readdir, struct dirent *, (DIR *dirp));
|
||||
_GL_CXXALIASWARN (readdir);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef readdir
|
||||
# if HAVE_RAW_DECL_READDIR
|
||||
_GL_WARN_ON_USE (readdir, "readdir is not portable - "
|
||||
"use gnulib module readdir for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_REWINDDIR@
|
||||
# if !@HAVE_REWINDDIR@
|
||||
_GL_FUNCDECL_SYS (rewinddir, void, (DIR *dirp) _GL_ARG_NONNULL ((1)));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (rewinddir, void, (DIR *dirp));
|
||||
_GL_CXXALIASWARN (rewinddir);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef rewinddir
|
||||
# if HAVE_RAW_DECL_REWINDDIR
|
||||
_GL_WARN_ON_USE (rewinddir, "rewinddir is not portable - "
|
||||
"use gnulib module rewinddir for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_DIRFD@
|
||||
/* Return the file descriptor associated with the given directory stream,
|
||||
or -1 if none exists. */
|
||||
# if @REPLACE_DIRFD@
|
||||
/* On kLIBC, dirfd() is a macro that does not work. Undefine it. */
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) || defined dirfd
|
||||
# undef dirfd
|
||||
# define dirfd rpl_dirfd
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1)));
|
||||
_GL_CXXALIAS_RPL (dirfd, int, (DIR *));
|
||||
|
||||
# ifdef __KLIBC__
|
||||
/* Gnulib internal hooks needed to maintain the dirfd metadata. */
|
||||
_GL_EXTERN_C int _gl_register_dirp_fd (int fd, DIR *dirp)
|
||||
_GL_ARG_NONNULL ((2));
|
||||
_GL_EXTERN_C void _gl_unregister_dirp_fd (int fd);
|
||||
# endif
|
||||
# else
|
||||
# if defined __cplusplus && defined GNULIB_NAMESPACE && defined dirfd
|
||||
/* dirfd is defined as a macro and not as a function.
|
||||
Turn it into a function and get rid of the macro. */
|
||||
static inline int (dirfd) (DIR *dp) { return dirfd (dp); }
|
||||
# undef dirfd
|
||||
# endif
|
||||
# if !(@HAVE_DECL_DIRFD@ || defined dirfd)
|
||||
_GL_FUNCDECL_SYS (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1)));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (dirfd, int, (DIR *));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (dirfd);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef dirfd
|
||||
# if HAVE_RAW_DECL_DIRFD
|
||||
_GL_WARN_ON_USE (dirfd, "dirfd is unportable - "
|
||||
"use gnulib module dirfd for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_FDOPENDIR@
|
||||
/* Open a directory stream visiting the given directory file
|
||||
descriptor. Return NULL and set errno if fd is not visiting a
|
||||
directory. On success, this function consumes fd (it will be
|
||||
implicitly closed either by this function or by a subsequent
|
||||
closedir). */
|
||||
# if @REPLACE_FDOPENDIR@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef fdopendir
|
||||
# define fdopendir rpl_fdopendir
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (fdopendir, DIR *,
|
||||
(int fd)
|
||||
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
|
||||
_GL_CXXALIAS_RPL (fdopendir, DIR *, (int fd));
|
||||
# else
|
||||
# if !@HAVE_FDOPENDIR@ || !@HAVE_DECL_FDOPENDIR@ || __GNUC__ >= 11
|
||||
_GL_FUNCDECL_SYS (fdopendir, DIR *,
|
||||
(int fd)
|
||||
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (fdopendir, DIR *, (int fd));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (fdopendir);
|
||||
#else
|
||||
# if @GNULIB_CLOSEDIR@ && __GNUC__ >= 11 && !defined fdopendir
|
||||
/* For -Wmismatched-dealloc: Associate fdopendir with closedir or
|
||||
rpl_closedir. */
|
||||
_GL_FUNCDECL_SYS (fdopendir, DIR *,
|
||||
(int fd)
|
||||
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
|
||||
# endif
|
||||
# if defined GNULIB_POSIXCHECK
|
||||
# undef fdopendir
|
||||
# if HAVE_RAW_DECL_FDOPENDIR
|
||||
_GL_WARN_ON_USE (fdopendir, "fdopendir is unportable - "
|
||||
"use gnulib module fdopendir for portability");
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_SCANDIR@
|
||||
/* Scan the directory DIR, calling FILTER on each directory entry.
|
||||
Entries for which FILTER returns nonzero are individually malloc'd,
|
||||
sorted using qsort with CMP, and collected in a malloc'd array in
|
||||
*NAMELIST. Returns the number of entries selected, or -1 on error. */
|
||||
# if !@HAVE_SCANDIR@
|
||||
_GL_FUNCDECL_SYS (scandir, int,
|
||||
(const char *dir, struct dirent ***namelist,
|
||||
int (*filter) (const struct dirent *),
|
||||
int (*cmp) (const struct dirent **, const struct dirent **))
|
||||
_GL_ARG_NONNULL ((1, 2, 4)));
|
||||
# endif
|
||||
/* Need to cast, because on glibc systems, the fourth parameter is
|
||||
int (*cmp) (const void *, const void *). */
|
||||
_GL_CXXALIAS_SYS_CAST (scandir, int,
|
||||
(const char *dir, struct dirent ***namelist,
|
||||
int (*filter) (const struct dirent *),
|
||||
int (*cmp) (const struct dirent **, const struct dirent **)));
|
||||
_GL_CXXALIASWARN (scandir);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef scandir
|
||||
# if HAVE_RAW_DECL_SCANDIR
|
||||
_GL_WARN_ON_USE (scandir, "scandir is unportable - "
|
||||
"use gnulib module scandir for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_ALPHASORT@
|
||||
/* Compare two 'struct dirent' entries alphabetically. */
|
||||
# if !@HAVE_ALPHASORT@
|
||||
_GL_FUNCDECL_SYS (alphasort, int,
|
||||
(const struct dirent **, const struct dirent **)
|
||||
_GL_ATTRIBUTE_PURE
|
||||
_GL_ARG_NONNULL ((1, 2)));
|
||||
# endif
|
||||
/* Need to cast, because on glibc systems, the parameters are
|
||||
(const void *, const void *). */
|
||||
_GL_CXXALIAS_SYS_CAST (alphasort, int,
|
||||
(const struct dirent **, const struct dirent **));
|
||||
_GL_CXXALIASWARN (alphasort);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef alphasort
|
||||
# if HAVE_RAW_DECL_ALPHASORT
|
||||
_GL_WARN_ON_USE (alphasort, "alphasort is unportable - "
|
||||
"use gnulib module alphasort for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_DIRENT_H */
|
||||
#endif /* _@GUARD_PREFIX@_DIRENT_H */
|
|
@ -1,98 +0,0 @@
|
|||
/* dirfd.c -- return the file descriptor associated with an open DIR*
|
||||
|
||||
Copyright (C) 2001, 2006, 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Jim Meyering. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __KLIBC__
|
||||
# include <stdlib.h>
|
||||
# include <io.h>
|
||||
|
||||
static struct dirp_fd_list
|
||||
{
|
||||
DIR *dirp;
|
||||
int fd;
|
||||
struct dirp_fd_list *next;
|
||||
} *dirp_fd_start = NULL;
|
||||
|
||||
/* Register fd associated with dirp to dirp_fd_list. */
|
||||
int
|
||||
_gl_register_dirp_fd (int fd, DIR *dirp)
|
||||
{
|
||||
struct dirp_fd_list *new_dirp_fd = malloc (sizeof *new_dirp_fd);
|
||||
if (!new_dirp_fd)
|
||||
return -1;
|
||||
|
||||
new_dirp_fd->dirp = dirp;
|
||||
new_dirp_fd->fd = fd;
|
||||
new_dirp_fd->next = dirp_fd_start;
|
||||
|
||||
dirp_fd_start = new_dirp_fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unregister fd from dirp_fd_list with closing it */
|
||||
void
|
||||
_gl_unregister_dirp_fd (int fd)
|
||||
{
|
||||
struct dirp_fd_list *dirp_fd;
|
||||
struct dirp_fd_list *dirp_fd_prev;
|
||||
|
||||
for (dirp_fd_prev = NULL, dirp_fd = dirp_fd_start; dirp_fd;
|
||||
dirp_fd_prev = dirp_fd, dirp_fd = dirp_fd->next)
|
||||
{
|
||||
if (dirp_fd->fd == fd)
|
||||
{
|
||||
if (dirp_fd_prev)
|
||||
dirp_fd_prev->next = dirp_fd->next;
|
||||
else /* dirp_fd == dirp_fd_start */
|
||||
dirp_fd_start = dirp_fd_start->next;
|
||||
|
||||
close (fd);
|
||||
free (dirp_fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
dirfd (DIR *dir_p)
|
||||
{
|
||||
int fd = DIR_TO_FD (dir_p);
|
||||
if (fd == -1)
|
||||
#ifndef __KLIBC__
|
||||
errno = ENOTSUP;
|
||||
#else
|
||||
{
|
||||
struct dirp_fd_list *dirp_fd;
|
||||
|
||||
for (dirp_fd = dirp_fd_start; dirp_fd; dirp_fd = dirp_fd->next)
|
||||
if (dirp_fd->dirp == dir_p)
|
||||
return dirp_fd->fd;
|
||||
|
||||
errno = EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/* Convert 'double' to accurate string.
|
||||
|
||||
Copyright (C) 2010-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file 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 file 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#define LENGTH 2
|
||||
#include "ftoastr.c"
|
|
@ -1,53 +0,0 @@
|
|||
/* Convert double to timespec.
|
||||
|
||||
Copyright (C) 2011-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Paul Eggert */
|
||||
|
||||
/* Convert the double value SEC to a struct timespec. Round toward
|
||||
positive infinity. On overflow, return an extremal value. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "timespec.h"
|
||||
|
||||
#include "intprops.h"
|
||||
|
||||
struct timespec
|
||||
dtotimespec (double sec)
|
||||
{
|
||||
if (! (TYPE_MINIMUM (time_t) < sec))
|
||||
return make_timespec (TYPE_MINIMUM (time_t), 0);
|
||||
else if (! (sec < 1.0 + TYPE_MAXIMUM (time_t)))
|
||||
return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1);
|
||||
else
|
||||
{
|
||||
time_t s = sec;
|
||||
double frac = TIMESPEC_HZ * (sec - s);
|
||||
long ns = frac;
|
||||
ns += ns < frac;
|
||||
s += ns / TIMESPEC_HZ;
|
||||
ns %= TIMESPEC_HZ;
|
||||
|
||||
if (ns < 0)
|
||||
{
|
||||
s--;
|
||||
ns += TIMESPEC_HZ;
|
||||
}
|
||||
|
||||
return make_timespec (s, ns);
|
||||
}
|
||||
}
|
189
cross/lib/dup2.c
189
cross/lib/dup2.c
|
@ -1,189 +0,0 @@
|
|||
/* Duplicate an open file descriptor to a specified file descriptor.
|
||||
|
||||
Copyright (C) 1999, 2004-2007, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Paul Eggert */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#undef dup2
|
||||
|
||||
#if defined _WIN32 && ! defined __CYGWIN__
|
||||
|
||||
/* Get declarations of the native Windows API functions. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
|
||||
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
# include "msvc-inval.h"
|
||||
# endif
|
||||
|
||||
/* Get _get_osfhandle. */
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# include <io.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
static int
|
||||
dup2_nothrow (int fd, int desired_fd)
|
||||
{
|
||||
int result;
|
||||
|
||||
TRY_MSVC_INVAL
|
||||
{
|
||||
result = _dup2 (fd, desired_fd);
|
||||
}
|
||||
CATCH_MSVC_INVAL
|
||||
{
|
||||
errno = EBADF;
|
||||
result = -1;
|
||||
}
|
||||
DONE_MSVC_INVAL;
|
||||
|
||||
return result;
|
||||
}
|
||||
# else
|
||||
# define dup2_nothrow _dup2
|
||||
# endif
|
||||
|
||||
static int
|
||||
ms_windows_dup2 (int fd, int desired_fd)
|
||||
{
|
||||
int result;
|
||||
|
||||
/* If fd is closed, mingw hangs on dup2 (fd, fd). If fd is open,
|
||||
dup2 (fd, fd) returns 0, but all further attempts to use fd in
|
||||
future dup2 calls will hang. */
|
||||
if (fd == desired_fd)
|
||||
{
|
||||
if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Wine 1.0.1 return 0 when desired_fd is negative but not -1:
|
||||
https://bugs.winehq.org/show_bug.cgi?id=21289 */
|
||||
if (desired_fd < 0)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = dup2_nothrow (fd, desired_fd);
|
||||
|
||||
if (result == 0)
|
||||
result = desired_fd;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
# define dup2 ms_windows_dup2
|
||||
|
||||
#elif defined __KLIBC__
|
||||
|
||||
# include <InnoTekLIBC/backend.h>
|
||||
|
||||
static int
|
||||
klibc_dup2dirfd (int fd, int desired_fd)
|
||||
{
|
||||
int tempfd;
|
||||
int dupfd;
|
||||
|
||||
tempfd = open ("NUL", O_RDONLY);
|
||||
if (tempfd == -1)
|
||||
return -1;
|
||||
|
||||
if (tempfd == desired_fd)
|
||||
{
|
||||
close (tempfd);
|
||||
|
||||
char path[_MAX_PATH];
|
||||
if (__libc_Back_ioFHToPath (fd, path, sizeof (path)))
|
||||
return -1;
|
||||
|
||||
return open(path, O_RDONLY);
|
||||
}
|
||||
|
||||
dupfd = klibc_dup2dirfd (fd, desired_fd);
|
||||
|
||||
close (tempfd);
|
||||
|
||||
return dupfd;
|
||||
}
|
||||
|
||||
static int
|
||||
klibc_dup2 (int fd, int desired_fd)
|
||||
{
|
||||
int dupfd;
|
||||
struct stat sbuf;
|
||||
|
||||
dupfd = dup2 (fd, desired_fd);
|
||||
if (dupfd == -1 && errno == ENOTSUP \
|
||||
&& !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode))
|
||||
{
|
||||
close (desired_fd);
|
||||
|
||||
return klibc_dup2dirfd (fd, desired_fd);
|
||||
}
|
||||
|
||||
return dupfd;
|
||||
}
|
||||
|
||||
# define dup2 klibc_dup2
|
||||
#endif
|
||||
|
||||
int
|
||||
rpl_dup2 (int fd, int desired_fd)
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef F_GETFL
|
||||
/* On Linux kernels 2.6.26-2.6.29, dup2 (fd, fd) returns -EBADF.
|
||||
On Cygwin 1.5.x, dup2 (1, 1) returns 0.
|
||||
On Cygwin 1.7.17, dup2 (1, -1) dumps core.
|
||||
On Cygwin 1.7.25, dup2 (1, 256) can dump core.
|
||||
On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC. */
|
||||
# if HAVE_SETDTABLESIZE
|
||||
setdtablesize (desired_fd + 1);
|
||||
# endif
|
||||
if (desired_fd < 0)
|
||||
fd = desired_fd;
|
||||
if (fd == desired_fd)
|
||||
return fcntl (fd, F_GETFL) == -1 ? -1 : fd;
|
||||
#endif
|
||||
|
||||
result = dup2 (fd, desired_fd);
|
||||
|
||||
/* Correct an errno value on FreeBSD 6.1 and Cygwin 1.5.x. */
|
||||
if (result == -1 && errno == EMFILE)
|
||||
errno = EBADF;
|
||||
#if REPLACE_FCHDIR
|
||||
if (fd != desired_fd && result != -1)
|
||||
result = _gl_register_dup (fd, result);
|
||||
#endif
|
||||
return result;
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
/* Type-safe arrays which grow dynamically.
|
||||
Copyright 2021-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert and Bruno Haible, 2021. */
|
||||
|
||||
#ifndef _GL_DYNARRAY_H
|
||||
#define _GL_DYNARRAY_H
|
||||
|
||||
/* Before including this file, you need to define:
|
||||
|
||||
DYNARRAY_STRUCT
|
||||
The struct tag of dynamic array to be defined.
|
||||
|
||||
DYNARRAY_ELEMENT
|
||||
The type name of the element type. Elements are copied
|
||||
as if by memcpy, and can change address as the dynamic
|
||||
array grows.
|
||||
|
||||
DYNARRAY_PREFIX
|
||||
The prefix of the functions which are defined.
|
||||
|
||||
The following parameters are optional:
|
||||
|
||||
DYNARRAY_ELEMENT_FREE
|
||||
DYNARRAY_ELEMENT_FREE (E) is evaluated to deallocate the
|
||||
contents of elements. E is of type DYNARRAY_ELEMENT *.
|
||||
|
||||
DYNARRAY_ELEMENT_INIT
|
||||
DYNARRAY_ELEMENT_INIT (E) is evaluated to initialize a new
|
||||
element. E is of type DYNARRAY_ELEMENT *.
|
||||
If DYNARRAY_ELEMENT_FREE but not DYNARRAY_ELEMENT_INIT is
|
||||
defined, new elements are automatically zero-initialized.
|
||||
Otherwise, new elements have undefined contents.
|
||||
|
||||
DYNARRAY_INITIAL_SIZE
|
||||
The size of the statically allocated array (default:
|
||||
at least 2, more elements if they fit into 128 bytes).
|
||||
Must be a preprocessor constant. If DYNARRAY_INITIAL_SIZE is 0,
|
||||
there is no statically allocated array at, and all non-empty
|
||||
arrays are heap-allocated.
|
||||
|
||||
DYNARRAY_FINAL_TYPE
|
||||
The name of the type which holds the final array. If not
|
||||
defined, is PREFIX##finalize not provided. DYNARRAY_FINAL_TYPE
|
||||
must be a struct type, with members of type DYNARRAY_ELEMENT and
|
||||
size_t at the start (in this order).
|
||||
|
||||
These macros are undefined after this header file has been
|
||||
included.
|
||||
|
||||
The following types are provided (their members are private to the
|
||||
dynarray implementation):
|
||||
|
||||
struct DYNARRAY_STRUCT
|
||||
|
||||
The following functions are provided:
|
||||
*/
|
||||
|
||||
/* Initialize a dynamic array object. This must be called before any
|
||||
use of the object. */
|
||||
#if 0
|
||||
static void
|
||||
DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
/* Deallocate the dynamic array and its elements. */
|
||||
#if 0
|
||||
static void
|
||||
DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
/* Return true if the dynamic array is in an error state. */
|
||||
#if 0
|
||||
static bool
|
||||
DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
/* Mark the dynamic array as failed. All elements are deallocated as
|
||||
a side effect. */
|
||||
#if 0
|
||||
static void
|
||||
DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
/* Return the number of elements which have been added to the dynamic
|
||||
array. */
|
||||
#if 0
|
||||
static size_t
|
||||
DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
/* Return a pointer to the first array element, if any. For a
|
||||
zero-length array, the pointer can be NULL even though the dynamic
|
||||
array has not entered the failure state. */
|
||||
#if 0
|
||||
static DYNARRAY_ELEMENT *
|
||||
DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
/* Return a pointer one element past the last array element. For a
|
||||
zero-length array, the pointer can be NULL even though the dynamic
|
||||
array has not entered the failure state. */
|
||||
#if 0
|
||||
static DYNARRAY_ELEMENT *
|
||||
DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
/* Return a pointer to the array element at INDEX. Terminate the
|
||||
process if INDEX is out of bounds. */
|
||||
#if 0
|
||||
static DYNARRAY_ELEMENT *
|
||||
DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *list, size_t index);
|
||||
#endif
|
||||
|
||||
/* Add ITEM at the end of the array, enlarging it by one element.
|
||||
Mark *LIST as failed if the dynamic array allocation size cannot be
|
||||
increased. */
|
||||
#if 0
|
||||
static void
|
||||
DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *list,
|
||||
DYNARRAY_ELEMENT item);
|
||||
#endif
|
||||
|
||||
/* Allocate a place for a new element in *LIST and return a pointer to
|
||||
it. The pointer can be NULL if the dynamic array cannot be
|
||||
enlarged due to a memory allocation failure. */
|
||||
#if 0
|
||||
static DYNARRAY_ELEMENT *
|
||||
DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
/* Change the size of *LIST to SIZE. If SIZE is larger than the
|
||||
existing size, new elements are added (which can be initialized).
|
||||
Otherwise, the list is truncated, and elements are freed. Return
|
||||
false on memory allocation failure (and mark *LIST as failed). */
|
||||
#if 0
|
||||
static bool
|
||||
DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *list, size_t size);
|
||||
#endif
|
||||
|
||||
/* Remove the last element of LIST if it is present. */
|
||||
#if 0
|
||||
static void
|
||||
DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
/* Remove all elements from the list. The elements are freed, but the
|
||||
list itself is not. */
|
||||
#if 0
|
||||
static void
|
||||
DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *list);
|
||||
#endif
|
||||
|
||||
#if defined DYNARRAY_FINAL_TYPE
|
||||
/* Transfer the dynamic array to a permanent location at *RESULT.
|
||||
Returns true on success on false on allocation failure. In either
|
||||
case, *LIST is re-initialized and can be reused. A NULL pointer is
|
||||
stored in *RESULT if LIST refers to an empty list. On success, the
|
||||
pointer in *RESULT is heap-allocated and must be deallocated using
|
||||
free. */
|
||||
#if 0
|
||||
static bool
|
||||
DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *list,
|
||||
DYNARRAY_FINAL_TYPE *result);
|
||||
#endif
|
||||
#else /* !defined DYNARRAY_FINAL_TYPE */
|
||||
/* Transfer the dynamic array to a heap-allocated array and return a
|
||||
pointer to it. The pointer is NULL if memory allocation fails, or
|
||||
if the array is empty, so this function should be used only for
|
||||
arrays which are known not be empty (usually because they always
|
||||
have a sentinel at the end). If LENGTHP is not NULL, the array
|
||||
length is written to *LENGTHP. *LIST is re-initialized and can be
|
||||
reused. */
|
||||
#if 0
|
||||
static DYNARRAY_ELEMENT *
|
||||
DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *list,
|
||||
size_t *lengthp);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* A minimal example which provides a growing list of integers can be
|
||||
defined like this:
|
||||
|
||||
struct int_array
|
||||
{
|
||||
// Pointer to result array followed by its length,
|
||||
// as required by DYNARRAY_FINAL_TYPE.
|
||||
int *array;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
#define DYNARRAY_STRUCT dynarray_int
|
||||
#define DYNARRAY_ELEMENT int
|
||||
#define DYNARRAY_PREFIX dynarray_int_
|
||||
#define DYNARRAY_FINAL_TYPE struct int_array
|
||||
#include <malloc/dynarray-skeleton.c>
|
||||
|
||||
To create a three-element array with elements 1, 2, 3, use this
|
||||
code:
|
||||
|
||||
struct dynarray_int dyn;
|
||||
dynarray_int_init (&dyn);
|
||||
for (int i = 1; i <= 3; ++i)
|
||||
{
|
||||
int *place = dynarray_int_emplace (&dyn);
|
||||
assert (place != NULL);
|
||||
*place = i;
|
||||
}
|
||||
struct int_array result;
|
||||
bool ok = dynarray_int_finalize (&dyn, &result);
|
||||
assert (ok);
|
||||
assert (result.length == 3);
|
||||
assert (result.array[0] == 1);
|
||||
assert (result.array[1] == 2);
|
||||
assert (result.array[2] == 3);
|
||||
free (result.array);
|
||||
|
||||
If the elements contain resources which must be freed, define
|
||||
DYNARRAY_ELEMENT_FREE appropriately, like this:
|
||||
|
||||
struct str_array
|
||||
{
|
||||
char **array;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
#define DYNARRAY_STRUCT dynarray_str
|
||||
#define DYNARRAY_ELEMENT char *
|
||||
#define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr)
|
||||
#define DYNARRAY_PREFIX dynarray_str_
|
||||
#define DYNARRAY_FINAL_TYPE struct str_array
|
||||
#include <malloc/dynarray-skeleton.c>
|
||||
*/
|
||||
|
||||
|
||||
/* The implementation is imported from glibc. */
|
||||
|
||||
/* Avoid possible conflicts with symbols exported by the GNU libc. */
|
||||
#define __libc_dynarray_at_failure gl_dynarray_at_failure
|
||||
#define __libc_dynarray_emplace_enlarge gl_dynarray_emplace_enlarge
|
||||
#define __libc_dynarray_finalize gl_dynarray_finalize
|
||||
#define __libc_dynarray_resize_clear gl_dynarray_resize_clear
|
||||
#define __libc_dynarray_resize gl_dynarray_resize
|
||||
|
||||
#if defined DYNARRAY_STRUCT || defined DYNARRAY_ELEMENT || defined DYNARRAY_PREFIX
|
||||
|
||||
# ifndef _GL_LIKELY
|
||||
/* Rely on __builtin_expect, as provided by the module 'builtin-expect'. */
|
||||
# define _GL_LIKELY(cond) __builtin_expect ((cond), 1)
|
||||
# define _GL_UNLIKELY(cond) __builtin_expect ((cond), 0)
|
||||
# endif
|
||||
|
||||
/* Define auxiliary structs and declare auxiliary functions, common to all
|
||||
instantiations of dynarray. */
|
||||
# include <malloc/dynarray.gl.h>
|
||||
|
||||
/* Define the instantiation, specified through
|
||||
DYNARRAY_STRUCT
|
||||
DYNARRAY_ELEMENT
|
||||
DYNARRAY_PREFIX
|
||||
etc. */
|
||||
# include <malloc/dynarray-skeleton.gl.h>
|
||||
|
||||
#else
|
||||
|
||||
/* This file is being included from one of the malloc/dynarray_*.c files. */
|
||||
# include <malloc/dynarray.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _GL_DYNARRAY_H */
|
|
@ -1,83 +0,0 @@
|
|||
/* Threshold at which to diagnose ELOOP. Generic version.
|
||||
Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _ELOOP_THRESHOLD_H
|
||||
#define _ELOOP_THRESHOLD_H 1
|
||||
|
||||
#include <limits.h>
|
||||
#ifdef _LIBC
|
||||
# include <sys/param.h>
|
||||
# define _GL_ATTRIBUTE_CONST __attribute__ ((const))
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include "minmax.h"
|
||||
# define __sysconf sysconf
|
||||
# if (!defined SYMLOOP_MAX \
|
||||
&& ! (defined _SC_SYMLOOP_MAX && defined _POSIX_SYMLOOP_MAX))
|
||||
# define SYMLOOP_MAX 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* POSIX specifies SYMLOOP_MAX as the "Maximum number of symbolic
|
||||
links that can be reliably traversed in the resolution of a
|
||||
pathname in the absence of a loop." This makes it a minimum that
|
||||
we should certainly accept. But it leaves open the possibility
|
||||
that more might sometimes work--just not "reliably".
|
||||
|
||||
For example, Linux implements a complex policy whereby there is a
|
||||
small limit on the number of direct symlink traversals (a symlink
|
||||
to a symlink to a symlink), but larger limit on the total number of
|
||||
symlink traversals overall. Hence the SYMLOOP_MAX number should be
|
||||
the small one, but the limit library functions enforce on users
|
||||
should be the larger one.
|
||||
|
||||
So, we use the larger of the reported SYMLOOP_MAX (if any) and our
|
||||
own constant MIN_ELOOP_THRESHOLD, below. This constant should be
|
||||
large enough that it never rules out a file name and directory tree
|
||||
that the underlying system (i.e. calls to 'open' et al) would
|
||||
resolve successfully. It should be small enough that actual loops
|
||||
are detected without a huge number of iterations. */
|
||||
|
||||
#ifndef MIN_ELOOP_THRESHOLD
|
||||
# define MIN_ELOOP_THRESHOLD 40
|
||||
#endif
|
||||
|
||||
/* Return the maximum number of symlink traversals to permit
|
||||
before diagnosing ELOOP. */
|
||||
static inline unsigned int _GL_ATTRIBUTE_CONST
|
||||
__eloop_threshold (void)
|
||||
{
|
||||
#ifdef SYMLOOP_MAX
|
||||
const int symloop_max = SYMLOOP_MAX;
|
||||
#else
|
||||
/* The function is marked 'const' even though we use memory and
|
||||
call a function, because sysconf is required to return the
|
||||
same value in every call and so it must always be safe to
|
||||
call __eloop_threshold exactly once and reuse the value. */
|
||||
static long int sysconf_symloop_max;
|
||||
if (sysconf_symloop_max == 0)
|
||||
sysconf_symloop_max = __sysconf (_SC_SYMLOOP_MAX);
|
||||
const unsigned int symloop_max = (sysconf_symloop_max <= 0
|
||||
? _POSIX_SYMLOOP_MAX
|
||||
: sysconf_symloop_max);
|
||||
#endif
|
||||
|
||||
return MAX (symloop_max, MIN_ELOOP_THRESHOLD);
|
||||
}
|
||||
|
||||
#endif /* eloop-threshold.h */
|
|
@ -1,279 +0,0 @@
|
|||
/* A POSIX-like <errno.h>.
|
||||
|
||||
Copyright (C) 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_ERRNO_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#@INCLUDE_NEXT@ @NEXT_ERRNO_H@
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_ERRNO_H
|
||||
#define _@GUARD_PREFIX@_ERRNO_H
|
||||
|
||||
|
||||
/* On native Windows platforms, many macros are not defined. */
|
||||
# if defined _WIN32 && ! defined __CYGWIN__
|
||||
|
||||
/* These are the same values as defined by MSVC 10, for interoperability. */
|
||||
|
||||
# ifndef ENOMSG
|
||||
# define ENOMSG 122
|
||||
# define GNULIB_defined_ENOMSG 1
|
||||
# endif
|
||||
|
||||
# ifndef EIDRM
|
||||
# define EIDRM 111
|
||||
# define GNULIB_defined_EIDRM 1
|
||||
# endif
|
||||
|
||||
# ifndef ENOLINK
|
||||
# define ENOLINK 121
|
||||
# define GNULIB_defined_ENOLINK 1
|
||||
# endif
|
||||
|
||||
# ifndef EPROTO
|
||||
# define EPROTO 134
|
||||
# define GNULIB_defined_EPROTO 1
|
||||
# endif
|
||||
|
||||
# ifndef EBADMSG
|
||||
# define EBADMSG 104
|
||||
# define GNULIB_defined_EBADMSG 1
|
||||
# endif
|
||||
|
||||
# ifndef EOVERFLOW
|
||||
# define EOVERFLOW 132
|
||||
# define GNULIB_defined_EOVERFLOW 1
|
||||
# endif
|
||||
|
||||
# ifndef ENOTSUP
|
||||
# define ENOTSUP 129
|
||||
# define GNULIB_defined_ENOTSUP 1
|
||||
# endif
|
||||
|
||||
# ifndef ENETRESET
|
||||
# define ENETRESET 117
|
||||
# define GNULIB_defined_ENETRESET 1
|
||||
# endif
|
||||
|
||||
# ifndef ECONNABORTED
|
||||
# define ECONNABORTED 106
|
||||
# define GNULIB_defined_ECONNABORTED 1
|
||||
# endif
|
||||
|
||||
# ifndef ECANCELED
|
||||
# define ECANCELED 105
|
||||
# define GNULIB_defined_ECANCELED 1
|
||||
# endif
|
||||
|
||||
# ifndef EOWNERDEAD
|
||||
# define EOWNERDEAD 133
|
||||
# define GNULIB_defined_EOWNERDEAD 1
|
||||
# endif
|
||||
|
||||
# ifndef ENOTRECOVERABLE
|
||||
# define ENOTRECOVERABLE 127
|
||||
# define GNULIB_defined_ENOTRECOVERABLE 1
|
||||
# endif
|
||||
|
||||
# ifndef EINPROGRESS
|
||||
# define EINPROGRESS 112
|
||||
# define EALREADY 103
|
||||
# define ENOTSOCK 128
|
||||
# define EDESTADDRREQ 109
|
||||
# define EMSGSIZE 115
|
||||
# define EPROTOTYPE 136
|
||||
# define ENOPROTOOPT 123
|
||||
# define EPROTONOSUPPORT 135
|
||||
# define EOPNOTSUPP 130
|
||||
# define EAFNOSUPPORT 102
|
||||
# define EADDRINUSE 100
|
||||
# define EADDRNOTAVAIL 101
|
||||
# define ENETDOWN 116
|
||||
# define ENETUNREACH 118
|
||||
# define ECONNRESET 108
|
||||
# define ENOBUFS 119
|
||||
# define EISCONN 113
|
||||
# define ENOTCONN 126
|
||||
# define ETIMEDOUT 138
|
||||
# define ECONNREFUSED 107
|
||||
# define ELOOP 114
|
||||
# define EHOSTUNREACH 110
|
||||
# define EWOULDBLOCK 140
|
||||
# define GNULIB_defined_ESOCK 1
|
||||
# endif
|
||||
|
||||
# ifndef ETXTBSY
|
||||
# define ETXTBSY 139
|
||||
# define ENODATA 120 /* not required by POSIX */
|
||||
# define ENOSR 124 /* not required by POSIX */
|
||||
# define ENOSTR 125 /* not required by POSIX */
|
||||
# define ETIME 137 /* not required by POSIX */
|
||||
# define EOTHER 131 /* not required by POSIX */
|
||||
# define GNULIB_defined_ESTREAMS 1
|
||||
# endif
|
||||
|
||||
/* These are intentionally the same values as the WSA* error numbers, defined
|
||||
in <winsock2.h>. */
|
||||
# define ESOCKTNOSUPPORT 10044 /* not required by POSIX */
|
||||
# define EPFNOSUPPORT 10046 /* not required by POSIX */
|
||||
# define ESHUTDOWN 10058 /* not required by POSIX */
|
||||
# define ETOOMANYREFS 10059 /* not required by POSIX */
|
||||
# define EHOSTDOWN 10064 /* not required by POSIX */
|
||||
# define EPROCLIM 10067 /* not required by POSIX */
|
||||
# define EUSERS 10068 /* not required by POSIX */
|
||||
# define EDQUOT 10069
|
||||
# define ESTALE 10070
|
||||
# define EREMOTE 10071 /* not required by POSIX */
|
||||
# define GNULIB_defined_EWINSOCK 1
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
/* On OSF/1 5.1, when _XOPEN_SOURCE_EXTENDED is not defined, the macros
|
||||
EMULTIHOP, ENOLINK, EOVERFLOW are not defined. */
|
||||
# if @EMULTIHOP_HIDDEN@
|
||||
# define EMULTIHOP @EMULTIHOP_VALUE@
|
||||
# define GNULIB_defined_EMULTIHOP 1
|
||||
# endif
|
||||
# if @ENOLINK_HIDDEN@
|
||||
# define ENOLINK @ENOLINK_VALUE@
|
||||
# define GNULIB_defined_ENOLINK 1
|
||||
# endif
|
||||
# if @EOVERFLOW_HIDDEN@
|
||||
# define EOVERFLOW @EOVERFLOW_VALUE@
|
||||
# define GNULIB_defined_EOVERFLOW 1
|
||||
# endif
|
||||
|
||||
|
||||
/* On OpenBSD 4.0 and on native Windows, the macros ENOMSG, EIDRM, ENOLINK,
|
||||
EPROTO, EMULTIHOP, EBADMSG, EOVERFLOW, ENOTSUP, ECANCELED are not defined.
|
||||
Likewise, on NonStop Kernel, EDQUOT is not defined.
|
||||
Define them here. Values >= 2000 seem safe to use: Solaris ESTALE = 151,
|
||||
HP-UX EWOULDBLOCK = 246, IRIX EDQUOT = 1133.
|
||||
|
||||
Note: When one of these systems defines some of these macros some day,
|
||||
binaries will have to be recompiled so that they recognizes the new
|
||||
errno values from the system. */
|
||||
|
||||
# ifndef ENOMSG
|
||||
# define ENOMSG 2000
|
||||
# define GNULIB_defined_ENOMSG 1
|
||||
# endif
|
||||
|
||||
# ifndef EIDRM
|
||||
# define EIDRM 2001
|
||||
# define GNULIB_defined_EIDRM 1
|
||||
# endif
|
||||
|
||||
# ifndef ENOLINK
|
||||
# define ENOLINK 2002
|
||||
# define GNULIB_defined_ENOLINK 1
|
||||
# endif
|
||||
|
||||
# ifndef EPROTO
|
||||
# define EPROTO 2003
|
||||
# define GNULIB_defined_EPROTO 1
|
||||
# endif
|
||||
|
||||
# ifndef EMULTIHOP
|
||||
# define EMULTIHOP 2004
|
||||
# define GNULIB_defined_EMULTIHOP 1
|
||||
# endif
|
||||
|
||||
# ifndef EBADMSG
|
||||
# define EBADMSG 2005
|
||||
# define GNULIB_defined_EBADMSG 1
|
||||
# endif
|
||||
|
||||
# ifndef EOVERFLOW
|
||||
# define EOVERFLOW 2006
|
||||
# define GNULIB_defined_EOVERFLOW 1
|
||||
# endif
|
||||
|
||||
# ifndef ENOTSUP
|
||||
# define ENOTSUP 2007
|
||||
# define GNULIB_defined_ENOTSUP 1
|
||||
# endif
|
||||
|
||||
# ifndef ENETRESET
|
||||
# define ENETRESET 2011
|
||||
# define GNULIB_defined_ENETRESET 1
|
||||
# endif
|
||||
|
||||
# ifndef ECONNABORTED
|
||||
# define ECONNABORTED 2012
|
||||
# define GNULIB_defined_ECONNABORTED 1
|
||||
# endif
|
||||
|
||||
# ifndef ESTALE
|
||||
# define ESTALE 2009
|
||||
# define GNULIB_defined_ESTALE 1
|
||||
# endif
|
||||
|
||||
# ifndef EDQUOT
|
||||
# define EDQUOT 2010
|
||||
# define GNULIB_defined_EDQUOT 1
|
||||
# endif
|
||||
|
||||
# ifndef ECANCELED
|
||||
# define ECANCELED 2008
|
||||
# define GNULIB_defined_ECANCELED 1
|
||||
# endif
|
||||
|
||||
/* On many platforms, the macros EOWNERDEAD and ENOTRECOVERABLE are not
|
||||
defined. */
|
||||
|
||||
# ifndef EOWNERDEAD
|
||||
# if defined __sun
|
||||
/* Use the same values as defined for Solaris >= 8, for
|
||||
interoperability. */
|
||||
# define EOWNERDEAD 58
|
||||
# define ENOTRECOVERABLE 59
|
||||
# elif defined _WIN32 && ! defined __CYGWIN__
|
||||
/* We have a conflict here: pthreads-win32 defines these values
|
||||
differently than MSVC 10. It's hairy to decide which one to use. */
|
||||
# if defined __MINGW32__ && !defined USE_WINDOWS_THREADS
|
||||
/* Use the same values as defined by pthreads-win32, for
|
||||
interoperability. */
|
||||
# define EOWNERDEAD 43
|
||||
# define ENOTRECOVERABLE 44
|
||||
# else
|
||||
/* Use the same values as defined by MSVC 10, for
|
||||
interoperability. */
|
||||
# define EOWNERDEAD 133
|
||||
# define ENOTRECOVERABLE 127
|
||||
# endif
|
||||
# else
|
||||
# define EOWNERDEAD 2013
|
||||
# define ENOTRECOVERABLE 2014
|
||||
# endif
|
||||
# define GNULIB_defined_EOWNERDEAD 1
|
||||
# define GNULIB_defined_ENOTRECOVERABLE 1
|
||||
# endif
|
||||
|
||||
# ifndef EILSEQ
|
||||
# define EILSEQ 2015
|
||||
# define GNULIB_defined_EILSEQ 1
|
||||
# endif
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_ERRNO_H */
|
||||
#endif /* _@GUARD_PREFIX@_ERRNO_H */
|
|
@ -1,226 +0,0 @@
|
|||
/* euidaccess -- check if effective user id can access file
|
||||
|
||||
Copyright (C) 1990-1991, 1995, 1998, 2000, 2003-2006, 2008-2023 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by David MacKenzie and Torbjorn Granlund.
|
||||
Adapted for GNU C library by Roland McGrath. */
|
||||
|
||||
#ifndef _LIBC
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#if defined _WIN32 && ! defined __CYGWIN__
|
||||
# include <io.h>
|
||||
#else
|
||||
# include "root-uid.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBGEN_H
|
||||
# include <libgen.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef __set_errno
|
||||
# define __set_errno(val) errno = (val)
|
||||
#endif
|
||||
|
||||
#if defined EACCES && !defined EACCESS
|
||||
# define EACCESS EACCES
|
||||
#endif
|
||||
|
||||
#ifndef F_OK
|
||||
# define F_OK 0
|
||||
# define X_OK 1
|
||||
# define W_OK 2
|
||||
# define R_OK 4
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _LIBC
|
||||
|
||||
# define access __access
|
||||
# define getuid __getuid
|
||||
# define getgid __getgid
|
||||
# define geteuid __geteuid
|
||||
# define getegid __getegid
|
||||
# define group_member __group_member
|
||||
# define euidaccess __euidaccess
|
||||
# undef stat
|
||||
# define stat stat64
|
||||
|
||||
#endif
|
||||
|
||||
/* Return 0 if the user has permission of type MODE on FILE;
|
||||
otherwise, return -1 and set 'errno'.
|
||||
Like access, except that it uses the effective user and group
|
||||
id's instead of the real ones, and it does not always check for read-only
|
||||
file system, text busy, etc. */
|
||||
|
||||
int
|
||||
euidaccess (const char *file, int mode)
|
||||
{
|
||||
#if HAVE_FACCESSAT /* glibc, AIX 7, Solaris 11, Cygwin 1.7 */
|
||||
return faccessat (AT_FDCWD, file, mode, AT_EACCESS);
|
||||
#elif defined EFF_ONLY_OK /* IRIX, OSF/1, Interix */
|
||||
return access (file, mode | EFF_ONLY_OK);
|
||||
#elif defined ACC_SELF /* AIX */
|
||||
return accessx (file, mode, ACC_SELF);
|
||||
#elif HAVE_EACCESS /* FreeBSD */
|
||||
return eaccess (file, mode);
|
||||
#elif defined _WIN32 && ! defined __CYGWIN__ /* mingw */
|
||||
return _access (file, mode);
|
||||
#else /* Mac OS X, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, BeOS */
|
||||
|
||||
uid_t uid = getuid ();
|
||||
gid_t gid = getgid ();
|
||||
uid_t euid = geteuid ();
|
||||
gid_t egid = getegid ();
|
||||
struct stat stats;
|
||||
|
||||
# if HAVE_DECL_SETREGID && PREFER_NONREENTRANT_EUIDACCESS
|
||||
|
||||
/* Define PREFER_NONREENTRANT_EUIDACCESS if you prefer euidaccess to
|
||||
return the correct result even if this would make it
|
||||
nonreentrant. Define this only if your entire application is
|
||||
safe even if the uid or gid might temporarily change. If your
|
||||
application uses signal handlers or threads it is probably not
|
||||
safe. */
|
||||
|
||||
if (mode == F_OK)
|
||||
{
|
||||
int result = stat (file, &stats);
|
||||
return result != 0 && errno == EOVERFLOW ? 0 : result;
|
||||
}
|
||||
else
|
||||
{
|
||||
int result;
|
||||
int saved_errno;
|
||||
|
||||
if (uid != euid)
|
||||
setreuid (euid, uid);
|
||||
if (gid != egid)
|
||||
setregid (egid, gid);
|
||||
|
||||
result = access (file, mode);
|
||||
saved_errno = errno;
|
||||
|
||||
/* Restore them. */
|
||||
if (uid != euid)
|
||||
setreuid (uid, euid);
|
||||
if (gid != egid)
|
||||
setregid (gid, egid);
|
||||
|
||||
errno = saved_errno;
|
||||
return result;
|
||||
}
|
||||
|
||||
# else
|
||||
|
||||
/* The following code assumes the traditional Unix model, and is not
|
||||
correct on systems that have ACLs or the like. However, it's
|
||||
better than nothing, and it is reentrant. */
|
||||
|
||||
unsigned int granted;
|
||||
if (uid == euid && gid == egid)
|
||||
/* If we are not set-uid or set-gid, access does the same. */
|
||||
return access (file, mode);
|
||||
|
||||
if (stat (file, &stats) == -1)
|
||||
return mode == F_OK && errno == EOVERFLOW ? 0 : -1;
|
||||
|
||||
/* The super-user can read and write any file, and execute any file
|
||||
that anyone can execute. */
|
||||
if (euid == ROOT_UID
|
||||
&& ((mode & X_OK) == 0
|
||||
|| (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
|
||||
return 0;
|
||||
|
||||
/* Convert the mode to traditional form, clearing any bogus bits. */
|
||||
if (R_OK == 4 && W_OK == 2 && X_OK == 1 && F_OK == 0)
|
||||
mode &= 7;
|
||||
else
|
||||
mode = ((mode & R_OK ? 4 : 0)
|
||||
+ (mode & W_OK ? 2 : 0)
|
||||
+ (mode & X_OK ? 1 : 0));
|
||||
|
||||
if (mode == 0)
|
||||
return 0; /* The file exists. */
|
||||
|
||||
/* Convert the file's permission bits to traditional form. */
|
||||
if (S_IRUSR == (4 << 6) && S_IWUSR == (2 << 6) && S_IXUSR == (1 << 6)
|
||||
&& S_IRGRP == (4 << 3) && S_IWGRP == (2 << 3) && S_IXGRP == (1 << 3)
|
||||
&& S_IROTH == (4 << 0) && S_IWOTH == (2 << 0) && S_IXOTH == (1 << 0))
|
||||
granted = stats.st_mode;
|
||||
else
|
||||
granted = ((stats.st_mode & S_IRUSR ? 4 << 6 : 0)
|
||||
+ (stats.st_mode & S_IWUSR ? 2 << 6 : 0)
|
||||
+ (stats.st_mode & S_IXUSR ? 1 << 6 : 0)
|
||||
+ (stats.st_mode & S_IRGRP ? 4 << 3 : 0)
|
||||
+ (stats.st_mode & S_IWGRP ? 2 << 3 : 0)
|
||||
+ (stats.st_mode & S_IXGRP ? 1 << 3 : 0)
|
||||
+ (stats.st_mode & S_IROTH ? 4 << 0 : 0)
|
||||
+ (stats.st_mode & S_IWOTH ? 2 << 0 : 0)
|
||||
+ (stats.st_mode & S_IXOTH ? 1 << 0 : 0));
|
||||
|
||||
if (euid == stats.st_uid)
|
||||
granted >>= 6;
|
||||
else if (egid == stats.st_gid || group_member (stats.st_gid))
|
||||
granted >>= 3;
|
||||
|
||||
if ((mode & ~granted) == 0)
|
||||
return 0;
|
||||
__set_errno (EACCESS);
|
||||
return -1;
|
||||
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
#undef euidaccess
|
||||
#ifdef weak_alias
|
||||
weak_alias (__euidaccess, euidaccess)
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
# include <error.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *file;
|
||||
int mode;
|
||||
int err;
|
||||
|
||||
if (argc < 3)
|
||||
abort ();
|
||||
file = argv[1];
|
||||
mode = atoi (argv[2]);
|
||||
|
||||
err = euidaccess (file, mode);
|
||||
printf ("%d\n", err);
|
||||
if (err != 0)
|
||||
error (0, errno, "%s", file);
|
||||
exit (0);
|
||||
}
|
||||
#endif
|
|
@ -1,21 +0,0 @@
|
|||
/* Information about executables.
|
||||
|
||||
Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define _GL_EXECINFO_INLINE _GL_EXTERN_INLINE
|
||||
#include "execinfo.h"
|
|
@ -1,57 +0,0 @@
|
|||
/* Information about executables.
|
||||
|
||||
Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert. */
|
||||
|
||||
#ifndef _GL_EXECINFO_H
|
||||
#define _GL_EXECINFO_H
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef _GL_EXECINFO_INLINE
|
||||
# define _GL_EXECINFO_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
_GL_EXECINFO_INLINE int
|
||||
backtrace (void **buffer, int size)
|
||||
{
|
||||
(void) buffer;
|
||||
(void) size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_GL_EXECINFO_INLINE char **
|
||||
backtrace_symbols (void *const *buffer, int size)
|
||||
{
|
||||
(void) buffer;
|
||||
(void) size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_GL_EXECINFO_INLINE void
|
||||
backtrace_symbols_fd (void *const *buffer, int size, int fd)
|
||||
{
|
||||
(void) buffer;
|
||||
(void) size;
|
||||
(void) fd;
|
||||
}
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif
|
|
@ -1,74 +0,0 @@
|
|||
/* Erasure of sensitive data, generic implementation.
|
||||
Copyright (C) 2016-2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* An assembler implementation of explicit_bzero can be created as an
|
||||
assembler alias of an optimized bzero implementation.
|
||||
Architecture-specific implementations also need to define
|
||||
__explicit_bzero_chk. */
|
||||
|
||||
#if !_LIBC
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* memset_s need this define */
|
||||
#if HAVE_MEMSET_S
|
||||
# define __STDC_WANT_LIB_EXT1__ 1
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#if _LIBC
|
||||
/* glibc-internal users use __explicit_bzero_chk, and explicit_bzero
|
||||
redirects to that. */
|
||||
# undef explicit_bzero
|
||||
#endif
|
||||
|
||||
/* Set LEN bytes of S to 0. The compiler will not delete a call to
|
||||
this function, even if S is dead after the call. */
|
||||
void
|
||||
explicit_bzero (void *s, size_t len)
|
||||
{
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
(void) SecureZeroMemory (s, len);
|
||||
#elif HAVE_EXPLICIT_MEMSET
|
||||
explicit_memset (s, '\0', len);
|
||||
#elif HAVE_MEMSET_S
|
||||
(void) memset_s (s, len, '\0', len);
|
||||
#elif defined __GNUC__ && !defined __clang__
|
||||
memset (s, '\0', len);
|
||||
/* Compiler barrier. */
|
||||
asm volatile ("" ::: "memory");
|
||||
#elif defined __clang__
|
||||
memset (s, '\0', len);
|
||||
/* Compiler barrier. */
|
||||
/* With asm ("" ::: "memory") LLVM analyzes uses of 's' and finds that the
|
||||
whole thing is dead and eliminates it. Use 'g' to work around this
|
||||
problem. See <https://bugs.llvm.org/show_bug.cgi?id=15495#c11>. */
|
||||
__asm__ volatile ("" : : "g"(s) : "memory");
|
||||
#else
|
||||
/* Invoke memset through a volatile function pointer. This defeats compiler
|
||||
optimizations. */
|
||||
void * (* const volatile volatile_memset) (void *, int, size_t) = memset;
|
||||
(void) volatile_memset (s, '\0', len);
|
||||
#endif
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/* Check the access rights of a file relative to an open directory.
|
||||
Copyright (C) 2009-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Eric Blake */
|
||||
|
||||
/* If the user's config.h happens to include <unistd.h>, let it include only
|
||||
the system's <unistd.h> here, so that orig_faccessat doesn't recurse to
|
||||
rpl_faccessat. */
|
||||
#define _GL_INCLUDING_UNISTD_H
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#undef _GL_INCLUDING_UNISTD_H
|
||||
|
||||
#if HAVE_FACCESSAT
|
||||
static int
|
||||
orig_faccessat (int fd, char const *name, int mode, int flag)
|
||||
{
|
||||
return faccessat (fd, name, mode, flag);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write "unistd.h" here, not <unistd.h>, otherwise OSF/1 5.1 DTK cc
|
||||
eliminates this include because of the preliminary #include <unistd.h>
|
||||
above. */
|
||||
#include "unistd.h"
|
||||
|
||||
#ifndef HAVE_ACCESS
|
||||
/* Mingw lacks access, but it also lacks real vs. effective ids, so
|
||||
the gnulib euidaccess module is good enough. */
|
||||
# undef access
|
||||
# define access euidaccess
|
||||
#endif
|
||||
|
||||
#if HAVE_FACCESSAT
|
||||
|
||||
int
|
||||
rpl_faccessat (int fd, char const *file, int mode, int flag)
|
||||
{
|
||||
int result = orig_faccessat (fd, file, mode, flag);
|
||||
|
||||
if (result == 0 && file[strlen (file) - 1] == '/')
|
||||
{
|
||||
struct stat st;
|
||||
result = fstatat (fd, file, &st, 0);
|
||||
if (result == 0 && !S_ISDIR (st.st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else /* !HAVE_FACCESSAT */
|
||||
|
||||
/* Invoke access or euidaccess 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
|
||||
(access|euidaccess)/restore_cwd. If either the save_cwd or the
|
||||
restore_cwd fails, then give a diagnostic and exit nonzero.
|
||||
Note that this implementation only supports AT_EACCESS, although some
|
||||
native versions also support AT_SYMLINK_NOFOLLOW. */
|
||||
|
||||
# define AT_FUNC_NAME faccessat
|
||||
# define AT_FUNC_F1 euidaccess
|
||||
# define AT_FUNC_F2 access
|
||||
# define AT_FUNC_USE_F1_COND AT_EACCESS
|
||||
# define AT_FUNC_POST_FILE_PARAM_DECLS , int mode, int flag
|
||||
# define AT_FUNC_POST_FILE_ARGS , mode
|
||||
# include "at-func.c"
|
||||
|
||||
#endif
|
|
@ -1,142 +0,0 @@
|
|||
/* Change the protections of file relative to an open directory.
|
||||
Copyright (C) 2006, 2009-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Jim Meyering and Paul Eggert */
|
||||
|
||||
/* If the user's config.h happens to include <sys/stat.h>, let it include only
|
||||
the system's <sys/stat.h> here, so that orig_fchmodat doesn't recurse to
|
||||
rpl_fchmodat. */
|
||||
#define __need_system_sys_stat_h
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <sys/stat.h>
|
||||
#undef __need_system_sys_stat_h
|
||||
|
||||
#if HAVE_FCHMODAT
|
||||
static int
|
||||
orig_fchmodat (int dir, char const *file, mode_t mode, int flags)
|
||||
{
|
||||
return fchmodat (dir, file, mode, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __osf__
|
||||
/* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc
|
||||
eliminates this include because of the preliminary #include <sys/stat.h>
|
||||
above. */
|
||||
# include "sys/stat.h"
|
||||
#else
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <intprops.h>
|
||||
|
||||
/* Invoke chmod or lchmod on 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 (chmod|lchmod)/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. */
|
||||
|
||||
#if HAVE_FCHMODAT
|
||||
int
|
||||
fchmodat (int dir, char const *file, mode_t mode, int flags)
|
||||
{
|
||||
# if HAVE_NEARLY_WORKING_FCHMODAT
|
||||
/* Correct the trailing slash handling. */
|
||||
size_t len = strlen (file);
|
||||
if (len && file[len - 1] == '/')
|
||||
{
|
||||
struct stat st;
|
||||
if (fstatat (dir, file, &st, flags & AT_SYMLINK_NOFOLLOW) < 0)
|
||||
return -1;
|
||||
if (!S_ISDIR (st.st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
# if NEED_FCHMODAT_NONSYMLINK_FIX
|
||||
if (flags == AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
# if HAVE_READLINKAT
|
||||
char readlink_buf[1];
|
||||
|
||||
# ifdef O_PATH
|
||||
/* Open a file descriptor with O_NOFOLLOW, to make sure we don't
|
||||
follow symbolic links, if /proc is mounted. O_PATH is used to
|
||||
avoid a failure if the file is not readable.
|
||||
Cf. <https://sourceware.org/bugzilla/show_bug.cgi?id=14578> */
|
||||
int fd = openat (dir, file, O_PATH | O_NOFOLLOW | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
int err;
|
||||
if (0 <= readlinkat (fd, "", readlink_buf, sizeof readlink_buf))
|
||||
err = EOPNOTSUPP;
|
||||
else if (errno == EINVAL)
|
||||
{
|
||||
static char const fmt[] = "/proc/self/fd/%d";
|
||||
char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
|
||||
sprintf (buf, fmt, fd);
|
||||
err = chmod (buf, mode) == 0 ? 0 : errno == ENOENT ? -1 : errno;
|
||||
}
|
||||
else
|
||||
err = errno == ENOENT ? -1 : errno;
|
||||
|
||||
close (fd);
|
||||
|
||||
errno = err;
|
||||
if (0 <= err)
|
||||
return err == 0 ? 0 : -1;
|
||||
# endif
|
||||
|
||||
/* O_PATH + /proc is not supported. */
|
||||
|
||||
if (0 <= readlinkat (dir, file, readlink_buf, sizeof readlink_buf))
|
||||
{
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
|
||||
/* Fall back on orig_fchmodat with no flags, despite a possible race. */
|
||||
flags = 0;
|
||||
}
|
||||
# endif
|
||||
|
||||
return orig_fchmodat (dir, file, mode, flags);
|
||||
}
|
||||
#else
|
||||
# define AT_FUNC_NAME fchmodat
|
||||
# define AT_FUNC_F1 lchmod
|
||||
# define AT_FUNC_F2 chmod
|
||||
# define AT_FUNC_USE_F1_COND 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"
|
||||
#endif
|
|
@ -1,629 +0,0 @@
|
|||
/* Provide file descriptor control.
|
||||
|
||||
Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Eric Blake <ebb9@byu.net>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __KLIBC__
|
||||
# define INCL_DOS
|
||||
# include <os2.h>
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 && ! defined __CYGWIN__
|
||||
/* Get declarations of the native Windows API functions. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
|
||||
/* Get _get_osfhandle. */
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# include <io.h>
|
||||
# endif
|
||||
|
||||
/* Upper bound on getdtablesize(). See lib/getdtablesize.c. */
|
||||
# define OPEN_MAX_MAX 0x10000
|
||||
|
||||
/* Duplicate OLDFD into the first available slot of at least NEWFD,
|
||||
which must be positive, with FLAGS determining whether the duplicate
|
||||
will be inheritable. */
|
||||
static int
|
||||
dupfd (int oldfd, int newfd, int flags)
|
||||
{
|
||||
/* Mingw has no way to create an arbitrary fd. Iterate until all
|
||||
file descriptors less than newfd are filled up. */
|
||||
HANDLE curr_process = GetCurrentProcess ();
|
||||
HANDLE old_handle = (HANDLE) _get_osfhandle (oldfd);
|
||||
unsigned char fds_to_close[OPEN_MAX_MAX / CHAR_BIT];
|
||||
unsigned int fds_to_close_bound = 0;
|
||||
int result;
|
||||
BOOL inherit = flags & O_CLOEXEC ? FALSE : TRUE;
|
||||
int mode;
|
||||
|
||||
if (newfd < 0 || getdtablesize () <= newfd)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (old_handle == INVALID_HANDLE_VALUE
|
||||
|| (mode = _setmode (oldfd, O_BINARY)) == -1)
|
||||
{
|
||||
/* oldfd is not open, or is an unassigned standard file
|
||||
descriptor. */
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
_setmode (oldfd, mode);
|
||||
flags |= mode;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HANDLE new_handle;
|
||||
int duplicated_fd;
|
||||
unsigned int index;
|
||||
|
||||
if (!DuplicateHandle (curr_process, /* SourceProcessHandle */
|
||||
old_handle, /* SourceHandle */
|
||||
curr_process, /* TargetProcessHandle */
|
||||
(PHANDLE) &new_handle, /* TargetHandle */
|
||||
(DWORD) 0, /* DesiredAccess */
|
||||
inherit, /* InheritHandle */
|
||||
DUPLICATE_SAME_ACCESS)) /* Options */
|
||||
{
|
||||
switch (GetLastError ())
|
||||
{
|
||||
case ERROR_TOO_MANY_OPEN_FILES:
|
||||
errno = EMFILE;
|
||||
break;
|
||||
case ERROR_INVALID_HANDLE:
|
||||
case ERROR_INVALID_TARGET_HANDLE:
|
||||
case ERROR_DIRECT_ACCESS_HANDLE:
|
||||
errno = EBADF;
|
||||
break;
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
case ERROR_INVALID_FUNCTION:
|
||||
case ERROR_INVALID_ACCESS:
|
||||
errno = EINVAL;
|
||||
break;
|
||||
default:
|
||||
errno = EACCES;
|
||||
break;
|
||||
}
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
duplicated_fd = _open_osfhandle ((intptr_t) new_handle, flags);
|
||||
if (duplicated_fd < 0)
|
||||
{
|
||||
CloseHandle (new_handle);
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
if (newfd <= duplicated_fd)
|
||||
{
|
||||
result = duplicated_fd;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the bit duplicated_fd in fds_to_close[]. */
|
||||
index = (unsigned int) duplicated_fd / CHAR_BIT;
|
||||
if (fds_to_close_bound <= index)
|
||||
{
|
||||
if (sizeof fds_to_close <= index)
|
||||
/* Need to increase OPEN_MAX_MAX. */
|
||||
abort ();
|
||||
memset (fds_to_close + fds_to_close_bound, '\0',
|
||||
index + 1 - fds_to_close_bound);
|
||||
fds_to_close_bound = index + 1;
|
||||
}
|
||||
fds_to_close[index] |= 1 << ((unsigned int) duplicated_fd % CHAR_BIT);
|
||||
}
|
||||
|
||||
/* Close the previous fds that turned out to be too small. */
|
||||
{
|
||||
int saved_errno = errno;
|
||||
unsigned int duplicated_fd;
|
||||
|
||||
for (duplicated_fd = 0;
|
||||
duplicated_fd < fds_to_close_bound * CHAR_BIT;
|
||||
duplicated_fd++)
|
||||
if ((fds_to_close[duplicated_fd / CHAR_BIT]
|
||||
>> (duplicated_fd % CHAR_BIT))
|
||||
& 1)
|
||||
close (duplicated_fd);
|
||||
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
# if REPLACE_FCHDIR
|
||||
if (0 <= result)
|
||||
result = _gl_register_dup (oldfd, result);
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif /* W32 */
|
||||
|
||||
/* Forward declarations, because we '#undef fcntl' in the middle of this
|
||||
compilation unit. */
|
||||
/* Our implementation of fcntl (fd, F_DUPFD, target). */
|
||||
static int rpl_fcntl_DUPFD (int fd, int target);
|
||||
/* Our implementation of fcntl (fd, F_DUPFD_CLOEXEC, target). */
|
||||
static int rpl_fcntl_DUPFD_CLOEXEC (int fd, int target);
|
||||
#ifdef __KLIBC__
|
||||
/* Adds support for fcntl on directories. */
|
||||
static int klibc_fcntl (int fd, int action, /* arg */...);
|
||||
#endif
|
||||
|
||||
|
||||
/* Perform the specified ACTION on the file descriptor FD, possibly
|
||||
using the argument ARG further described below. This replacement
|
||||
handles the following actions, and forwards all others on to the
|
||||
native fcntl. An unrecognized ACTION returns -1 with errno set to
|
||||
EINVAL.
|
||||
|
||||
F_DUPFD - duplicate FD, with int ARG being the minimum target fd.
|
||||
If successful, return the duplicate, which will be inheritable;
|
||||
otherwise return -1 and set errno.
|
||||
|
||||
F_DUPFD_CLOEXEC - duplicate FD, with int ARG being the minimum
|
||||
target fd. If successful, return the duplicate, which will not be
|
||||
inheritable; otherwise return -1 and set errno.
|
||||
|
||||
F_GETFD - ARG need not be present. If successful, return a
|
||||
non-negative value containing the descriptor flags of FD (only
|
||||
FD_CLOEXEC is portable, but other flags may be present); otherwise
|
||||
return -1 and set errno. */
|
||||
|
||||
int
|
||||
fcntl (int fd, int action, /* arg */...)
|
||||
#undef fcntl
|
||||
#ifdef __KLIBC__
|
||||
# define fcntl klibc_fcntl
|
||||
#endif
|
||||
{
|
||||
va_list arg;
|
||||
int result = -1;
|
||||
va_start (arg, action);
|
||||
switch (action)
|
||||
{
|
||||
case F_DUPFD:
|
||||
{
|
||||
int target = va_arg (arg, int);
|
||||
result = rpl_fcntl_DUPFD (fd, target);
|
||||
break;
|
||||
}
|
||||
|
||||
case F_DUPFD_CLOEXEC:
|
||||
{
|
||||
int target = va_arg (arg, int);
|
||||
result = rpl_fcntl_DUPFD_CLOEXEC (fd, target);
|
||||
break;
|
||||
}
|
||||
|
||||
#if !HAVE_FCNTL
|
||||
case F_GETFD:
|
||||
{
|
||||
# if defined _WIN32 && ! defined __CYGWIN__
|
||||
HANDLE handle = (HANDLE) _get_osfhandle (fd);
|
||||
DWORD flags;
|
||||
if (handle == INVALID_HANDLE_VALUE
|
||||
|| GetHandleInformation (handle, &flags) == 0)
|
||||
errno = EBADF;
|
||||
else
|
||||
result = (flags & HANDLE_FLAG_INHERIT) ? 0 : FD_CLOEXEC;
|
||||
# else /* !W32 */
|
||||
/* Use dup2 to reject invalid file descriptors. No way to
|
||||
access this information, so punt. */
|
||||
if (0 <= dup2 (fd, fd))
|
||||
result = 0;
|
||||
# endif /* !W32 */
|
||||
break;
|
||||
} /* F_GETFD */
|
||||
#endif /* !HAVE_FCNTL */
|
||||
|
||||
/* Implementing F_SETFD on mingw is not trivial - there is no
|
||||
API for changing the O_NOINHERIT bit on an fd, and merely
|
||||
changing the HANDLE_FLAG_INHERIT bit on the underlying handle
|
||||
can lead to odd state. It may be possible by duplicating the
|
||||
handle, using _open_osfhandle with the right flags, then
|
||||
using dup2 to move the duplicate onto the original, but that
|
||||
is not supported for now. */
|
||||
|
||||
default:
|
||||
{
|
||||
#if HAVE_FCNTL
|
||||
switch (action)
|
||||
{
|
||||
#ifdef F_BARRIERFSYNC /* macOS */
|
||||
case F_BARRIERFSYNC:
|
||||
#endif
|
||||
#ifdef F_CHKCLEAN /* macOS */
|
||||
case F_CHKCLEAN:
|
||||
#endif
|
||||
#ifdef F_CLOSEM /* NetBSD, HP-UX */
|
||||
case F_CLOSEM:
|
||||
#endif
|
||||
#ifdef F_FLUSH_DATA /* macOS */
|
||||
case F_FLUSH_DATA:
|
||||
#endif
|
||||
#ifdef F_FREEZE_FS /* macOS */
|
||||
case F_FREEZE_FS:
|
||||
#endif
|
||||
#ifdef F_FULLFSYNC /* macOS */
|
||||
case F_FULLFSYNC:
|
||||
#endif
|
||||
#ifdef F_GETCONFINED /* macOS */
|
||||
case F_GETCONFINED:
|
||||
#endif
|
||||
#ifdef F_GETDEFAULTPROTLEVEL /* macOS */
|
||||
case F_GETDEFAULTPROTLEVEL:
|
||||
#endif
|
||||
#ifdef F_GETFD /* POSIX */
|
||||
case F_GETFD:
|
||||
#endif
|
||||
#ifdef F_GETFL /* POSIX */
|
||||
case F_GETFL:
|
||||
#endif
|
||||
#ifdef F_GETLEASE /* Linux */
|
||||
case F_GETLEASE:
|
||||
#endif
|
||||
#ifdef F_GETNOSIGPIPE /* macOS */
|
||||
case F_GETNOSIGPIPE:
|
||||
#endif
|
||||
#ifdef F_GETOWN /* POSIX */
|
||||
case F_GETOWN:
|
||||
#endif
|
||||
#ifdef F_GETPIPE_SZ /* Linux */
|
||||
case F_GETPIPE_SZ:
|
||||
#endif
|
||||
#ifdef F_GETPROTECTIONCLASS /* macOS */
|
||||
case F_GETPROTECTIONCLASS:
|
||||
#endif
|
||||
#ifdef F_GETPROTECTIONLEVEL /* macOS */
|
||||
case F_GETPROTECTIONLEVEL:
|
||||
#endif
|
||||
#ifdef F_GET_SEALS /* Linux */
|
||||
case F_GET_SEALS:
|
||||
#endif
|
||||
#ifdef F_GETSIG /* Linux */
|
||||
case F_GETSIG:
|
||||
#endif
|
||||
#ifdef F_MAXFD /* NetBSD */
|
||||
case F_MAXFD:
|
||||
#endif
|
||||
#ifdef F_RECYCLE /* macOS */
|
||||
case F_RECYCLE:
|
||||
#endif
|
||||
#ifdef F_SETFIFOENH /* HP-UX */
|
||||
case F_SETFIFOENH:
|
||||
#endif
|
||||
#ifdef F_THAW_FS /* macOS */
|
||||
case F_THAW_FS:
|
||||
#endif
|
||||
/* These actions take no argument. */
|
||||
result = fcntl (fd, action);
|
||||
break;
|
||||
|
||||
#ifdef F_ADD_SEALS /* Linux */
|
||||
case F_ADD_SEALS:
|
||||
#endif
|
||||
#ifdef F_BADFD /* Solaris */
|
||||
case F_BADFD:
|
||||
#endif
|
||||
#ifdef F_CHECK_OPENEVT /* macOS */
|
||||
case F_CHECK_OPENEVT:
|
||||
#endif
|
||||
#ifdef F_DUP2FD /* FreeBSD, AIX, Solaris */
|
||||
case F_DUP2FD:
|
||||
#endif
|
||||
#ifdef F_DUP2FD_CLOEXEC /* FreeBSD, Solaris */
|
||||
case F_DUP2FD_CLOEXEC:
|
||||
#endif
|
||||
#ifdef F_DUP2FD_CLOFORK /* Solaris */
|
||||
case F_DUP2FD_CLOFORK:
|
||||
#endif
|
||||
#ifdef F_DUPFD /* POSIX */
|
||||
case F_DUPFD:
|
||||
#endif
|
||||
#ifdef F_DUPFD_CLOEXEC /* POSIX */
|
||||
case F_DUPFD_CLOEXEC:
|
||||
#endif
|
||||
#ifdef F_DUPFD_CLOFORK /* Solaris */
|
||||
case F_DUPFD_CLOFORK:
|
||||
#endif
|
||||
#ifdef F_GETXFL /* Solaris */
|
||||
case F_GETXFL:
|
||||
#endif
|
||||
#ifdef F_GLOBAL_NOCACHE /* macOS */
|
||||
case F_GLOBAL_NOCACHE:
|
||||
#endif
|
||||
#ifdef F_MAKECOMPRESSED /* macOS */
|
||||
case F_MAKECOMPRESSED:
|
||||
#endif
|
||||
#ifdef F_MOVEDATAEXTENTS /* macOS */
|
||||
case F_MOVEDATAEXTENTS:
|
||||
#endif
|
||||
#ifdef F_NOCACHE /* macOS */
|
||||
case F_NOCACHE:
|
||||
#endif
|
||||
#ifdef F_NODIRECT /* macOS */
|
||||
case F_NODIRECT:
|
||||
#endif
|
||||
#ifdef F_NOTIFY /* Linux */
|
||||
case F_NOTIFY:
|
||||
#endif
|
||||
#ifdef F_OPLKACK /* IRIX */
|
||||
case F_OPLKACK:
|
||||
#endif
|
||||
#ifdef F_OPLKREG /* IRIX */
|
||||
case F_OPLKREG:
|
||||
#endif
|
||||
#ifdef F_RDAHEAD /* macOS */
|
||||
case F_RDAHEAD:
|
||||
#endif
|
||||
#ifdef F_SETBACKINGSTORE /* macOS */
|
||||
case F_SETBACKINGSTORE:
|
||||
#endif
|
||||
#ifdef F_SETCONFINED /* macOS */
|
||||
case F_SETCONFINED:
|
||||
#endif
|
||||
#ifdef F_SETFD /* POSIX */
|
||||
case F_SETFD:
|
||||
#endif
|
||||
#ifdef F_SETFL /* POSIX */
|
||||
case F_SETFL:
|
||||
#endif
|
||||
#ifdef F_SETLEASE /* Linux */
|
||||
case F_SETLEASE:
|
||||
#endif
|
||||
#ifdef F_SETNOSIGPIPE /* macOS */
|
||||
case F_SETNOSIGPIPE:
|
||||
#endif
|
||||
#ifdef F_SETOWN /* POSIX */
|
||||
case F_SETOWN:
|
||||
#endif
|
||||
#ifdef F_SETPIPE_SZ /* Linux */
|
||||
case F_SETPIPE_SZ:
|
||||
#endif
|
||||
#ifdef F_SETPROTECTIONCLASS /* macOS */
|
||||
case F_SETPROTECTIONCLASS:
|
||||
#endif
|
||||
#ifdef F_SETSIG /* Linux */
|
||||
case F_SETSIG:
|
||||
#endif
|
||||
#ifdef F_SINGLE_WRITER /* macOS */
|
||||
case F_SINGLE_WRITER:
|
||||
#endif
|
||||
/* These actions take an 'int' argument. */
|
||||
{
|
||||
int x = va_arg (arg, int);
|
||||
result = fcntl (fd, action, x);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Other actions take a pointer argument. */
|
||||
{
|
||||
void *p = va_arg (arg, void *);
|
||||
result = fcntl (fd, action, p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#else
|
||||
errno = EINVAL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_end (arg);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
rpl_fcntl_DUPFD (int fd, int target)
|
||||
{
|
||||
int result;
|
||||
#if !HAVE_FCNTL
|
||||
result = dupfd (fd, target, 0);
|
||||
#elif FCNTL_DUPFD_BUGGY || REPLACE_FCHDIR
|
||||
/* Detect invalid target; needed for cygwin 1.5.x. */
|
||||
if (target < 0 || getdtablesize () <= target)
|
||||
{
|
||||
result = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Haiku alpha 2 loses fd flags on original. */
|
||||
int flags = fcntl (fd, F_GETFD);
|
||||
if (flags < 0)
|
||||
result = -1;
|
||||
else
|
||||
{
|
||||
result = fcntl (fd, F_DUPFD, target);
|
||||
if (0 <= result && fcntl (fd, F_SETFD, flags) == -1)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
close (result);
|
||||
result = -1;
|
||||
errno = saved_errno;
|
||||
}
|
||||
# if REPLACE_FCHDIR
|
||||
if (0 <= result)
|
||||
result = _gl_register_dup (fd, result);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
result = fcntl (fd, F_DUPFD, target);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
rpl_fcntl_DUPFD_CLOEXEC (int fd, int target)
|
||||
{
|
||||
int result;
|
||||
#if !HAVE_FCNTL
|
||||
result = dupfd (fd, target, O_CLOEXEC);
|
||||
#else /* HAVE_FCNTL */
|
||||
# if defined __NetBSD__ || defined __HAIKU__
|
||||
/* On NetBSD 9.0, the system fcntl (fd, F_DUPFD_CLOEXEC, target)
|
||||
has only the same effect as fcntl (fd, F_DUPFD, target). */
|
||||
/* On Haiku, the system fcntl (fd, F_DUPFD_CLOEXEC, target) sets
|
||||
the FD_CLOEXEC flag on fd, not on target. Therefore avoid the
|
||||
system fcntl in this case. */
|
||||
# define have_dupfd_cloexec -1
|
||||
# else
|
||||
/* Try the system call first, if the headers claim it exists
|
||||
(that is, if GNULIB_defined_F_DUPFD_CLOEXEC is 0), since we
|
||||
may be running with a glibc that has the macro but with an
|
||||
older kernel that does not support it. Cache the
|
||||
information on whether the system call really works, but
|
||||
avoid caching failure if the corresponding F_DUPFD fails
|
||||
for any reason. 0 = unknown, 1 = yes, -1 = no. */
|
||||
static int have_dupfd_cloexec = GNULIB_defined_F_DUPFD_CLOEXEC ? -1 : 0;
|
||||
if (0 <= have_dupfd_cloexec)
|
||||
{
|
||||
result = fcntl (fd, F_DUPFD_CLOEXEC, target);
|
||||
if (0 <= result || errno != EINVAL)
|
||||
{
|
||||
have_dupfd_cloexec = 1;
|
||||
# if REPLACE_FCHDIR
|
||||
if (0 <= result)
|
||||
result = _gl_register_dup (fd, result);
|
||||
# endif
|
||||
}
|
||||
else
|
||||
{
|
||||
result = rpl_fcntl_DUPFD (fd, target);
|
||||
if (result >= 0)
|
||||
have_dupfd_cloexec = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
# endif
|
||||
result = rpl_fcntl_DUPFD (fd, target);
|
||||
if (0 <= result && have_dupfd_cloexec == -1)
|
||||
{
|
||||
int flags = fcntl (result, F_GETFD);
|
||||
if (flags < 0 || fcntl (result, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
close (result);
|
||||
errno = saved_errno;
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_FCNTL */
|
||||
return result;
|
||||
}
|
||||
|
||||
#undef fcntl
|
||||
|
||||
#ifdef __KLIBC__
|
||||
|
||||
static int
|
||||
klibc_fcntl (int fd, int action, /* arg */...)
|
||||
{
|
||||
va_list arg_ptr;
|
||||
int arg;
|
||||
struct stat sbuf;
|
||||
int result;
|
||||
|
||||
va_start (arg_ptr, action);
|
||||
arg = va_arg (arg_ptr, int);
|
||||
result = fcntl (fd, action, arg);
|
||||
/* EPERM for F_DUPFD, ENOTSUP for others */
|
||||
if (result == -1 && (errno == EPERM || errno == ENOTSUP)
|
||||
&& !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode))
|
||||
{
|
||||
ULONG ulMode;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case F_DUPFD:
|
||||
/* Find available fd */
|
||||
while (fcntl (arg, F_GETFL) != -1 || errno != EBADF)
|
||||
arg++;
|
||||
|
||||
result = dup2 (fd, arg);
|
||||
break;
|
||||
|
||||
/* Using underlying APIs is right ? */
|
||||
case F_GETFD:
|
||||
if (DosQueryFHState (fd, &ulMode))
|
||||
break;
|
||||
|
||||
result = (ulMode & OPEN_FLAGS_NOINHERIT) ? FD_CLOEXEC : 0;
|
||||
break;
|
||||
|
||||
case F_SETFD:
|
||||
if (arg & ~FD_CLOEXEC)
|
||||
break;
|
||||
|
||||
if (DosQueryFHState (fd, &ulMode))
|
||||
break;
|
||||
|
||||
if (arg & FD_CLOEXEC)
|
||||
ulMode |= OPEN_FLAGS_NOINHERIT;
|
||||
else
|
||||
ulMode &= ~OPEN_FLAGS_NOINHERIT;
|
||||
|
||||
/* Filter supported flags. */
|
||||
ulMode &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR
|
||||
| OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT);
|
||||
|
||||
if (DosSetFHState (fd, ulMode))
|
||||
break;
|
||||
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case F_GETFL:
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case F_SETFL:
|
||||
if (arg != 0)
|
||||
break;
|
||||
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
va_end (arg_ptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,445 +0,0 @@
|
|||
/* Like <fcntl.h>, but with non-working flags defined to 0.
|
||||
|
||||
Copyright (C) 2006-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Paul Eggert */
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
#if defined __need_system_fcntl_h
|
||||
/* Special invocation convention. */
|
||||
|
||||
/* Needed before <sys/stat.h>.
|
||||
May also define off_t to a 64-bit type on native Windows. */
|
||||
#include <sys/types.h>
|
||||
/* On some systems other than glibc, <sys/stat.h> is a prerequisite of
|
||||
<fcntl.h>. On glibc systems, we would like to avoid namespace pollution.
|
||||
But on glibc systems, <fcntl.h> includes <sys/stat.h> inside an
|
||||
extern "C" { ... } block, which leads to errors in C++ mode with the
|
||||
overridden <sys/stat.h> from gnulib. These errors are known to be gone
|
||||
with g++ version >= 4.3. */
|
||||
#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && (defined __ICC || !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))))
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#@INCLUDE_NEXT@ @NEXT_FCNTL_H@
|
||||
|
||||
/* Native Windows platforms declare open(), creat() in <io.h>. */
|
||||
#if (@GNULIB_CREAT@ || @GNULIB_OPEN@ || defined GNULIB_POSIXCHECK) \
|
||||
&& (defined _WIN32 && ! defined __CYGWIN__)
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Normal invocation convention. */
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_FCNTL_H
|
||||
|
||||
/* Needed before <sys/stat.h>.
|
||||
May also define off_t to a 64-bit type on native Windows. */
|
||||
#include <sys/types.h>
|
||||
/* On some systems other than glibc, <sys/stat.h> is a prerequisite of
|
||||
<fcntl.h>. On glibc systems, we would like to avoid namespace pollution.
|
||||
But on glibc systems, <fcntl.h> includes <sys/stat.h> inside an
|
||||
extern "C" { ... } block, which leads to errors in C++ mode with the
|
||||
overridden <sys/stat.h> from gnulib. These errors are known to be gone
|
||||
with g++ version >= 4.3. */
|
||||
#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && (defined __ICC || !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))))
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#@INCLUDE_NEXT@ @NEXT_FCNTL_H@
|
||||
|
||||
/* Native Windows platforms declare open(), creat() in <io.h>. */
|
||||
#if (@GNULIB_CREAT@ || @GNULIB_OPEN@ || defined GNULIB_POSIXCHECK) \
|
||||
&& (defined _WIN32 && ! defined __CYGWIN__)
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_FCNTL_H
|
||||
#define _@GUARD_PREFIX@_FCNTL_H
|
||||
|
||||
#ifndef __GLIBC__ /* Avoid namespace pollution on glibc systems. */
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
||||
|
||||
/* The definition of _GL_ARG_NONNULL is copied here. */
|
||||
|
||||
/* The definition of _GL_WARN_ON_USE is copied here. */
|
||||
|
||||
|
||||
/* Declare overridden functions. */
|
||||
|
||||
#if @GNULIB_CREAT@
|
||||
# if @REPLACE_CREAT@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef creat
|
||||
# define creat rpl_creat
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (creat, int, (const char *filename, mode_t mode)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
_GL_CXXALIAS_RPL (creat, int, (const char *filename, mode_t mode));
|
||||
# elif defined _WIN32 && !defined __CYGWIN__
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef creat
|
||||
# define creat _creat
|
||||
# endif
|
||||
_GL_CXXALIAS_MDA (creat, int, (const char *filename, mode_t mode));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (creat, int, (const char *filename, mode_t mode));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (creat);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef creat
|
||||
/* Assume creat is always declared. */
|
||||
_GL_WARN_ON_USE (creat, "creat is not always POSIX compliant - "
|
||||
"use gnulib module creat for portability");
|
||||
#elif @GNULIB_MDA_CREAT@
|
||||
/* On native Windows, map 'creat' to '_creat', so that -loldnames is not
|
||||
required. In C++ with GNULIB_NAMESPACE, avoid differences between
|
||||
platforms by defining GNULIB_NAMESPACE::creat always. */
|
||||
# if defined _WIN32 && !defined __CYGWIN__
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef creat
|
||||
# define creat _creat
|
||||
# endif
|
||||
/* Need to cast, because in mingw the last argument is 'int mode'. */
|
||||
_GL_CXXALIAS_MDA_CAST (creat, int, (const char *filename, mode_t mode));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (creat, int, (const char *filename, mode_t mode));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (creat);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_FCNTL@
|
||||
# if @REPLACE_FCNTL@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef fcntl
|
||||
# define fcntl rpl_fcntl
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (fcntl, int, (int fd, int action, ...));
|
||||
_GL_CXXALIAS_RPL (fcntl, int, (int fd, int action, ...));
|
||||
# if !GNULIB_defined_rpl_fcntl
|
||||
# define GNULIB_defined_rpl_fcntl 1
|
||||
# endif
|
||||
# else
|
||||
# if !@HAVE_FCNTL@
|
||||
_GL_FUNCDECL_SYS (fcntl, int, (int fd, int action, ...));
|
||||
# if !GNULIB_defined_fcntl
|
||||
# define GNULIB_defined_fcntl 1
|
||||
# endif
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (fcntl, int, (int fd, int action, ...));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (fcntl);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef fcntl
|
||||
# if HAVE_RAW_DECL_FCNTL
|
||||
_GL_WARN_ON_USE (fcntl, "fcntl is not always POSIX compliant - "
|
||||
"use gnulib module fcntl for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_OPEN@
|
||||
# if @REPLACE_OPEN@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef open
|
||||
# define open rpl_open
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
|
||||
# elif defined _WIN32 && !defined __CYGWIN__
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef open
|
||||
# define open _open
|
||||
# endif
|
||||
_GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
|
||||
# endif
|
||||
/* On HP-UX 11, in C++ mode, open() is defined as an inline function with a
|
||||
default argument. _GL_CXXALIASWARN does not work in this case. */
|
||||
# if !defined __hpux
|
||||
_GL_CXXALIASWARN (open);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef open
|
||||
/* Assume open is always declared. */
|
||||
_GL_WARN_ON_USE (open, "open is not always POSIX compliant - "
|
||||
"use gnulib module open for portability");
|
||||
#elif @GNULIB_MDA_OPEN@
|
||||
/* On native Windows, map 'open' to '_open', so that -loldnames is not
|
||||
required. In C++ with GNULIB_NAMESPACE, avoid differences between
|
||||
platforms by defining GNULIB_NAMESPACE::open always. */
|
||||
# if defined _WIN32 && !defined __CYGWIN__
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef open
|
||||
# define open _open
|
||||
# endif
|
||||
_GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
|
||||
# endif
|
||||
# if !defined __hpux
|
||||
_GL_CXXALIASWARN (open);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_OPENAT@
|
||||
# if @REPLACE_OPENAT@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef openat
|
||||
# define openat rpl_openat
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (openat, int,
|
||||
(int fd, char const *file, int flags, /* mode_t mode */ ...)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
_GL_CXXALIAS_RPL (openat, int,
|
||||
(int fd, char const *file, int flags, /* mode_t mode */ ...));
|
||||
# else
|
||||
# if !@HAVE_OPENAT@
|
||||
_GL_FUNCDECL_SYS (openat, int,
|
||||
(int fd, char const *file, int flags, /* mode_t mode */ ...)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (openat, int,
|
||||
(int fd, char const *file, int flags, /* mode_t mode */ ...));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (openat);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef openat
|
||||
# if HAVE_RAW_DECL_OPENAT
|
||||
_GL_WARN_ON_USE (openat, "openat is not portable - "
|
||||
"use gnulib module openat for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Fix up the FD_* macros, only known to be missing on mingw. */
|
||||
|
||||
#ifndef FD_CLOEXEC
|
||||
# define FD_CLOEXEC 1
|
||||
#endif
|
||||
|
||||
/* Fix up the supported F_* macros. Intentionally leave other F_*
|
||||
macros undefined. Only known to be missing on mingw. */
|
||||
|
||||
#ifndef F_DUPFD_CLOEXEC
|
||||
# define F_DUPFD_CLOEXEC 0x40000000
|
||||
/* Witness variable: 1 if gnulib defined F_DUPFD_CLOEXEC, 0 otherwise. */
|
||||
# define GNULIB_defined_F_DUPFD_CLOEXEC 1
|
||||
#else
|
||||
# define GNULIB_defined_F_DUPFD_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
#ifndef F_DUPFD
|
||||
# define F_DUPFD 1
|
||||
#endif
|
||||
|
||||
#ifndef F_GETFD
|
||||
# define F_GETFD 2
|
||||
#endif
|
||||
|
||||
/* Fix up the O_* macros. */
|
||||
|
||||
/* AIX 7.1 with XL C 12.1 defines O_CLOEXEC, O_NOFOLLOW, and O_TTY_INIT
|
||||
to values outside 'int' range, so omit these misdefinitions.
|
||||
But avoid namespace pollution on non-AIX systems. */
|
||||
#ifdef _AIX
|
||||
# include <limits.h>
|
||||
# if defined O_CLOEXEC && ! (INT_MIN <= O_CLOEXEC && O_CLOEXEC <= INT_MAX)
|
||||
# undef O_CLOEXEC
|
||||
# endif
|
||||
# if defined O_NOFOLLOW && ! (INT_MIN <= O_NOFOLLOW && O_NOFOLLOW <= INT_MAX)
|
||||
# undef O_NOFOLLOW
|
||||
# endif
|
||||
# if defined O_TTY_INIT && ! (INT_MIN <= O_TTY_INIT && O_TTY_INIT <= INT_MAX)
|
||||
# undef O_TTY_INIT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined O_DIRECT && defined O_DIRECTIO
|
||||
/* Tru64 spells it 'O_DIRECTIO'. */
|
||||
# define O_DIRECT O_DIRECTIO
|
||||
#endif
|
||||
|
||||
#if !defined O_CLOEXEC && defined O_NOINHERIT
|
||||
/* Mingw spells it 'O_NOINHERIT'. */
|
||||
# define O_CLOEXEC O_NOINHERIT
|
||||
#endif
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
# define O_CLOEXEC 0x40000000 /* Try to not collide with system O_* flags. */
|
||||
# define GNULIB_defined_O_CLOEXEC 1
|
||||
#else
|
||||
# define GNULIB_defined_O_CLOEXEC 0
|
||||
#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_EXEC
|
||||
# define O_EXEC O_RDONLY /* This is often close enough in older systems. */
|
||||
#endif
|
||||
|
||||
#ifndef O_IGNORE_CTTY
|
||||
# define O_IGNORE_CTTY 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
|
||||
|
||||
/* If the gnulib module 'nonblocking' is in use, guarantee a working non-zero
|
||||
value of O_NONBLOCK. Otherwise, O_NONBLOCK is defined (above) to O_NDELAY
|
||||
or to 0 as fallback. */
|
||||
#if @GNULIB_NONBLOCKING@
|
||||
# if O_NONBLOCK
|
||||
# define GNULIB_defined_O_NONBLOCK 0
|
||||
# else
|
||||
# define GNULIB_defined_O_NONBLOCK 1
|
||||
# undef O_NONBLOCK
|
||||
# define O_NONBLOCK 0x40000000
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef O_NOCTTY
|
||||
# define O_NOCTTY 0
|
||||
#endif
|
||||
|
||||
#ifndef O_NOFOLLOW
|
||||
# define O_NOFOLLOW 0
|
||||
#endif
|
||||
|
||||
#ifndef O_NOLINK
|
||||
# define O_NOLINK 0
|
||||
#endif
|
||||
|
||||
#ifndef O_NOLINKS
|
||||
# define O_NOLINKS 0
|
||||
#endif
|
||||
|
||||
#ifndef O_NOTRANS
|
||||
# define O_NOTRANS 0
|
||||
#endif
|
||||
|
||||
#ifndef O_RSYNC
|
||||
# define O_RSYNC 0
|
||||
#endif
|
||||
|
||||
#ifndef O_SEARCH
|
||||
# define O_SEARCH O_RDONLY /* This is often close enough in older systems. */
|
||||
#endif
|
||||
|
||||
#ifndef O_SYNC
|
||||
# define O_SYNC 0
|
||||
#endif
|
||||
|
||||
#ifndef O_TTY_INIT
|
||||
# define O_TTY_INIT 0
|
||||
#endif
|
||||
|
||||
#if ~O_ACCMODE & (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
|
||||
# undef O_ACCMODE
|
||||
# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
|
||||
#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
|
||||
|
||||
#if defined __BEOS__ || defined __HAIKU__
|
||||
/* BeOS 5 and Haiku have 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
|
||||
|
||||
/* Fix up the AT_* macros. */
|
||||
|
||||
/* 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 the bug
|
||||
is present, undef AT_FDCWD here, so it can be redefined below. */
|
||||
#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553
|
||||
# undef AT_FDCWD
|
||||
#endif
|
||||
|
||||
/* Use the same bit pattern as Solaris 9, but with the proper
|
||||
signedness. The bit pattern is important, in case this actually is
|
||||
Solaris with the above workaround. */
|
||||
#ifndef AT_FDCWD
|
||||
# define AT_FDCWD (-3041965)
|
||||
#endif
|
||||
|
||||
/* Use the same values as Solaris 9. This shouldn't matter, but
|
||||
there's no real reason to differ. */
|
||||
#ifndef AT_SYMLINK_NOFOLLOW
|
||||
# define AT_SYMLINK_NOFOLLOW 4096
|
||||
#endif
|
||||
|
||||
#ifndef AT_REMOVEDIR
|
||||
# define AT_REMOVEDIR 1
|
||||
#endif
|
||||
|
||||
/* Solaris 9 lacks these two, so just pick unique values. */
|
||||
#ifndef AT_SYMLINK_FOLLOW
|
||||
# define AT_SYMLINK_FOLLOW 2
|
||||
#endif
|
||||
|
||||
#ifndef AT_EACCESS
|
||||
# define AT_EACCESS 4
|
||||
#endif
|
||||
|
||||
/* Ignore this flag if not supported. */
|
||||
#ifndef AT_NO_AUTOMOUNT
|
||||
# define AT_NO_AUTOMOUNT 0
|
||||
#endif
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_FCNTL_H */
|
||||
#endif /* _@GUARD_PREFIX@_FCNTL_H */
|
||||
#endif
|
|
@ -1,249 +0,0 @@
|
|||
/* provide a replacement fdopendir function
|
||||
Copyright (C) 2004-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Jim Meyering */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_FDOPENDIR
|
||||
|
||||
# include "openat.h"
|
||||
# include "openat-priv.h"
|
||||
# include "save-cwd.h"
|
||||
|
||||
# if GNULIB_DIRENT_SAFER
|
||||
# include "dirent--.h"
|
||||
# endif
|
||||
|
||||
# ifndef REPLACE_FCHDIR
|
||||
# define REPLACE_FCHDIR 0
|
||||
# endif
|
||||
|
||||
static DIR *fdopendir_with_dup (int, int, struct saved_cwd const *);
|
||||
static DIR *fd_clone_opendir (int, struct saved_cwd const *);
|
||||
|
||||
/* Replacement for POSIX fdopendir.
|
||||
|
||||
First, try to simulate it via opendir ("/proc/self/fd/..."). Failing
|
||||
that, simulate it by using fchdir metadata, or by doing
|
||||
save_cwd/fchdir/opendir(".")/restore_cwd.
|
||||
If either the save_cwd or the restore_cwd fails (relatively unlikely),
|
||||
then give a diagnostic and exit nonzero.
|
||||
|
||||
If successful, the resulting stream is based on FD in
|
||||
implementations where streams are based on file descriptors and in
|
||||
applications where no other thread or signal handler allocates or
|
||||
frees file descriptors. In other cases, consult dirfd on the result
|
||||
to find out whether FD is still being used.
|
||||
|
||||
Otherwise, this function works just like POSIX fdopendir.
|
||||
|
||||
W A R N I N G:
|
||||
|
||||
Unlike other fd-related functions, this one places constraints on FD.
|
||||
If this function returns successfully, FD is under control of the
|
||||
dirent.h system, and the caller should not close or modify the state of
|
||||
FD other than by the dirent.h functions. */
|
||||
# ifdef __KLIBC__
|
||||
# include <InnoTekLIBC/backend.h>
|
||||
|
||||
DIR *
|
||||
fdopendir (int fd)
|
||||
{
|
||||
char path[_MAX_PATH];
|
||||
DIR *dirp;
|
||||
|
||||
/* Get a path from fd */
|
||||
if (__libc_Back_ioFHToPath (fd, path, sizeof (path)))
|
||||
return NULL;
|
||||
|
||||
dirp = opendir (path);
|
||||
if (!dirp)
|
||||
return NULL;
|
||||
|
||||
/* Unregister fd registered by opendir() */
|
||||
_gl_unregister_dirp_fd (dirfd (dirp));
|
||||
|
||||
/* Register our fd */
|
||||
if (_gl_register_dirp_fd (fd, dirp))
|
||||
{
|
||||
int saved_errno = errno;
|
||||
|
||||
closedir (dirp);
|
||||
|
||||
errno = saved_errno;
|
||||
|
||||
dirp = NULL;
|
||||
}
|
||||
|
||||
return dirp;
|
||||
}
|
||||
# else
|
||||
DIR *
|
||||
fdopendir (int fd)
|
||||
{
|
||||
DIR *dir = fdopendir_with_dup (fd, -1, NULL);
|
||||
|
||||
if (! REPLACE_FCHDIR && ! dir)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
if (EXPECTED_ERRNO (saved_errno))
|
||||
{
|
||||
struct saved_cwd cwd;
|
||||
if (save_cwd (&cwd) != 0)
|
||||
openat_save_fail (errno);
|
||||
dir = fdopendir_with_dup (fd, -1, &cwd);
|
||||
saved_errno = errno;
|
||||
free_cwd (&cwd);
|
||||
errno = saved_errno;
|
||||
}
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
# endif
|
||||
|
||||
/* Like fdopendir, except that if OLDER_DUPFD is not -1, it is known
|
||||
to be a dup of FD which is less than FD - 1 and which will be
|
||||
closed by the caller and not otherwise used by the caller. This
|
||||
function makes sure that FD is closed and all file descriptors less
|
||||
than FD are open, and then calls fd_clone_opendir on a dup of FD.
|
||||
That way, barring race conditions, fd_clone_opendir returns a
|
||||
stream whose file descriptor is FD.
|
||||
|
||||
If REPLACE_FCHDIR or CWD is null, use opendir ("/proc/self/fd/...",
|
||||
falling back on fchdir metadata. Otherwise, CWD is a saved version
|
||||
of the working directory; use fchdir/opendir(".")/restore_cwd(CWD). */
|
||||
static DIR *
|
||||
fdopendir_with_dup (int fd, int older_dupfd, struct saved_cwd const *cwd)
|
||||
{
|
||||
int dupfd = dup (fd);
|
||||
if (dupfd < 0 && errno == EMFILE)
|
||||
dupfd = older_dupfd;
|
||||
if (dupfd < 0)
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
DIR *dir;
|
||||
int saved_errno;
|
||||
if (dupfd < fd - 1 && dupfd != older_dupfd)
|
||||
{
|
||||
dir = fdopendir_with_dup (fd, dupfd, cwd);
|
||||
saved_errno = errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
close (fd);
|
||||
dir = fd_clone_opendir (dupfd, cwd);
|
||||
saved_errno = errno;
|
||||
if (! dir)
|
||||
{
|
||||
int fd1 = dup (dupfd);
|
||||
if (fd1 != fd)
|
||||
openat_save_fail (fd1 < 0 ? errno : EBADF);
|
||||
}
|
||||
}
|
||||
|
||||
if (dupfd != older_dupfd)
|
||||
close (dupfd);
|
||||
errno = saved_errno;
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
/* Like fdopendir, except the result controls a clone of FD. It is
|
||||
the caller's responsibility both to close FD and (if the result is
|
||||
not null) to closedir the result. */
|
||||
static DIR *
|
||||
fd_clone_opendir (int fd, struct saved_cwd const *cwd)
|
||||
{
|
||||
if (REPLACE_FCHDIR || ! cwd)
|
||||
{
|
||||
DIR *dir = NULL;
|
||||
int saved_errno = EOPNOTSUPP;
|
||||
char buf[OPENAT_BUFFER_SIZE];
|
||||
char *proc_file = openat_proc_name (buf, fd, ".");
|
||||
if (proc_file)
|
||||
{
|
||||
dir = opendir (proc_file);
|
||||
saved_errno = errno;
|
||||
if (proc_file != buf)
|
||||
free (proc_file);
|
||||
}
|
||||
# if REPLACE_FCHDIR
|
||||
if (! dir && EXPECTED_ERRNO (saved_errno))
|
||||
{
|
||||
char const *name = _gl_directory_name (fd);
|
||||
DIR *dp = name ? opendir (name) : NULL;
|
||||
|
||||
/* The caller has done an elaborate dance to arrange for opendir to
|
||||
consume just the right file descriptor. If dirfd returns -1,
|
||||
though, we're on a system like mingw where opendir does not
|
||||
consume a file descriptor. Consume it via 'dup' instead. */
|
||||
if (dp && dirfd (dp) < 0)
|
||||
dup (fd);
|
||||
|
||||
return dp;
|
||||
}
|
||||
# endif
|
||||
errno = saved_errno;
|
||||
return dir;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fchdir (fd) != 0)
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
DIR *dir = opendir (".");
|
||||
int saved_errno = errno;
|
||||
if (restore_cwd (cwd) != 0)
|
||||
openat_restore_fail (errno);
|
||||
errno = saved_errno;
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else /* HAVE_FDOPENDIR */
|
||||
|
||||
# include <errno.h>
|
||||
# include <sys/stat.h>
|
||||
|
||||
# undef fdopendir
|
||||
|
||||
/* Like fdopendir, but work around GNU/Hurd bug by validating FD. */
|
||||
|
||||
DIR *
|
||||
rpl_fdopendir (int fd)
|
||||
{
|
||||
struct stat st;
|
||||
if (fstat (fd, &st))
|
||||
return NULL;
|
||||
if (!S_ISDIR (st.st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return NULL;
|
||||
}
|
||||
return fdopendir (fd);
|
||||
}
|
||||
|
||||
#endif /* HAVE_FDOPENDIR */
|
|
@ -1,621 +0,0 @@
|
|||
/* Test whether a file has a nontrivial ACL. -*- coding: utf-8 -*-
|
||||
|
||||
Copyright (C) 2002-2003, 2005-2023 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */
|
||||
|
||||
/* Without this pragma, gcc 4.7.0 20120126 may suggest that the
|
||||
file_has_acl function might be candidate for attribute 'const' */
|
||||
#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
|
||||
#endif
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
#include "acl-internal.h"
|
||||
|
||||
#if USE_ACL && GETXATTR_WITH_POSIX_ACLS
|
||||
# include <string.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/xattr.h>
|
||||
# include <linux/xattr.h>
|
||||
# ifndef XATTR_NAME_NFSV4_ACL
|
||||
# define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
|
||||
# endif
|
||||
|
||||
enum {
|
||||
/* ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000, */
|
||||
ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001,
|
||||
ACE4_IDENTIFIER_GROUP = 0x00000040
|
||||
};
|
||||
|
||||
/* Return 1 if given ACL in XDR format is non-trivial, 0 if it is trivial.
|
||||
-1 upon failure to determine it. Possibly change errno. Assume that
|
||||
the ACL is valid, except avoid undefined behavior even if invalid.
|
||||
|
||||
See <https://linux.die.net/man/5/nfs4_acl>. The NFSv4 acls are
|
||||
defined in Internet RFC 7530 and as such, every NFSv4 server
|
||||
supporting ACLs should support NFSv4 ACLs (they differ from from
|
||||
POSIX draft ACLs). The ACLs can be obtained via the
|
||||
nfsv4-acl-tools, e.g., the nfs4_getfacl command. Gnulib provides
|
||||
only basic support of NFSv4 ACLs, i.e., recognize trivial vs
|
||||
nontrivial ACLs. */
|
||||
|
||||
static int
|
||||
acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes)
|
||||
{
|
||||
enum { BYTES_PER_NETWORK_UINT = 4};
|
||||
|
||||
/* Grab the number of aces in the acl. */
|
||||
nbytes -= BYTES_PER_NETWORK_UINT;
|
||||
if (nbytes < 0)
|
||||
return -1;
|
||||
uint32_t num_aces = ntohl (*xattr++);
|
||||
if (6 < num_aces)
|
||||
return 1;
|
||||
int ace_found = 0;
|
||||
|
||||
for (int ace_n = 0; ace_n < num_aces; ace_n++)
|
||||
{
|
||||
/* Get the acl type and flag. Skip the mask; it's too risky to
|
||||
test it and it does not seem to be needed. Get the wholen. */
|
||||
nbytes -= 4 * BYTES_PER_NETWORK_UINT;
|
||||
if (nbytes < 0)
|
||||
return -1;
|
||||
uint32_t type = ntohl (xattr[0]);
|
||||
uint32_t flag = ntohl (xattr[1]);
|
||||
uint32_t wholen = ntohl (xattr[3]);
|
||||
xattr += 4;
|
||||
int whowords = (wholen / BYTES_PER_NETWORK_UINT
|
||||
+ (wholen % BYTES_PER_NETWORK_UINT != 0));
|
||||
int64_t wholen4 = whowords;
|
||||
wholen4 *= BYTES_PER_NETWORK_UINT;
|
||||
|
||||
/* Trivial ACLs have only ACE4_ACCESS_ALLOWED_ACE_TYPE or
|
||||
ACE4_ACCESS_DENIED_ACE_TYPE. */
|
||||
if (ACE4_ACCESS_DENIED_ACE_TYPE < type)
|
||||
return 1;
|
||||
|
||||
/* RFC 7530 says FLAG should be 0, but be generous to NetApp and
|
||||
also accept the group flag. */
|
||||
if (flag & ~ACE4_IDENTIFIER_GROUP)
|
||||
return 1;
|
||||
|
||||
/* Get the who string. Check NBYTES - WHOLEN4 before storing
|
||||
into NBYTES, to avoid truncation on conversion. */
|
||||
if (nbytes - wholen4 < 0)
|
||||
return -1;
|
||||
nbytes -= wholen4;
|
||||
|
||||
/* For a trivial ACL, max 6 (typically 3) ACEs, 3 allow, 3 deny.
|
||||
Check that there is at most one ACE of each TYPE and WHO. */
|
||||
int who2
|
||||
= (wholen == 6 && memcmp (xattr, "OWNER@", 6) == 0 ? 0
|
||||
: wholen == 6 && memcmp (xattr, "GROUP@", 6) == 0 ? 2
|
||||
: wholen == 9 && memcmp (xattr, "EVERYONE@", 9) == 0 ? 4
|
||||
: -1);
|
||||
if (who2 < 0)
|
||||
return 1;
|
||||
int ace_found_bit = 1 << (who2 | type);
|
||||
if (ace_found & ace_found_bit)
|
||||
return 1;
|
||||
ace_found |= ace_found_bit;
|
||||
|
||||
xattr += whowords;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return 1 if NAME has a nontrivial access control list,
|
||||
0 if ACLs are not supported, or if NAME has no or only a base ACL,
|
||||
and -1 (setting errno) on error. Note callers can determine
|
||||
if ACLs are not supported as errno is set in that case also.
|
||||
SB must be set to the stat buffer of NAME,
|
||||
obtained through stat() or lstat(). */
|
||||
|
||||
int
|
||||
file_has_acl (char const *name, struct stat const *sb)
|
||||
{
|
||||
#if USE_ACL
|
||||
if (! S_ISLNK (sb->st_mode))
|
||||
{
|
||||
|
||||
# if GETXATTR_WITH_POSIX_ACLS
|
||||
|
||||
ssize_t ret;
|
||||
int initial_errno = errno;
|
||||
|
||||
ret = getxattr (name, XATTR_NAME_POSIX_ACL_ACCESS, NULL, 0);
|
||||
if (ret < 0 && errno == ENODATA)
|
||||
ret = 0;
|
||||
else if (ret > 0)
|
||||
return 1;
|
||||
|
||||
if (ret == 0 && S_ISDIR (sb->st_mode))
|
||||
{
|
||||
ret = getxattr (name, XATTR_NAME_POSIX_ACL_DEFAULT, NULL, 0);
|
||||
if (ret < 0 && errno == ENODATA)
|
||||
ret = 0;
|
||||
else if (ret > 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Check for NFSv4 ACLs. The max length of a trivial
|
||||
ACL is 6 words for owner, 6 for group, 7 for everyone,
|
||||
all times 2 because there are both allow and deny ACEs.
|
||||
There are 6 words for owner because of type, flag, mask,
|
||||
wholen, "OWNER@"+pad and similarly for group; everyone is
|
||||
another word to hold "EVERYONE@". */
|
||||
uint32_t xattr[2 * (6 + 6 + 7)];
|
||||
|
||||
ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, sizeof xattr);
|
||||
if (ret < 0)
|
||||
switch (errno)
|
||||
{
|
||||
case ENODATA: return 0;
|
||||
case ERANGE : return 1; /* ACL must be nontrivial. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It looks like a trivial ACL, but investigate further. */
|
||||
ret = acl_nfs4_nontrivial (xattr, ret);
|
||||
if (ret < 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return ret;
|
||||
}
|
||||
errno = initial_errno;
|
||||
}
|
||||
}
|
||||
if (ret < 0)
|
||||
return - acl_errno_valid (errno);
|
||||
return ret;
|
||||
|
||||
# elif HAVE_ACL_GET_FILE
|
||||
|
||||
/* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
|
||||
/* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
int ret;
|
||||
|
||||
if (HAVE_ACL_EXTENDED_FILE) /* Linux */
|
||||
{
|
||||
/* On Linux, acl_extended_file is an optimized function: It only
|
||||
makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
|
||||
ACL_TYPE_DEFAULT. */
|
||||
ret = acl_extended_file (name);
|
||||
}
|
||||
else /* FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
{
|
||||
# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
|
||||
/* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS)
|
||||
and acl_get_file (name, ACL_TYPE_DEFAULT)
|
||||
always return NULL / EINVAL. There is no point in making
|
||||
these two useless calls. The real ACL is retrieved through
|
||||
acl_get_file (name, ACL_TYPE_EXTENDED). */
|
||||
acl_t acl = acl_get_file (name, ACL_TYPE_EXTENDED);
|
||||
if (acl)
|
||||
{
|
||||
ret = acl_extended_nontrivial (acl);
|
||||
acl_free (acl);
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
# else /* FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS);
|
||||
if (acl)
|
||||
{
|
||||
int saved_errno;
|
||||
|
||||
ret = acl_access_nontrivial (acl);
|
||||
saved_errno = errno;
|
||||
acl_free (acl);
|
||||
errno = saved_errno;
|
||||
# if HAVE_ACL_FREE_TEXT /* Tru64 */
|
||||
/* On OSF/1, acl_get_file (name, ACL_TYPE_DEFAULT) always
|
||||
returns NULL with errno not set. There is no point in
|
||||
making this call. */
|
||||
# else /* FreeBSD, IRIX, Cygwin >= 2.5 */
|
||||
/* On Linux, FreeBSD, IRIX, acl_get_file (name, ACL_TYPE_ACCESS)
|
||||
and acl_get_file (name, ACL_TYPE_DEFAULT) on a directory
|
||||
either both succeed or both fail; it depends on the
|
||||
file system. Therefore there is no point in making the second
|
||||
call if the first one already failed. */
|
||||
if (ret == 0 && S_ISDIR (sb->st_mode))
|
||||
{
|
||||
acl = acl_get_file (name, ACL_TYPE_DEFAULT);
|
||||
if (acl)
|
||||
{
|
||||
# ifdef __CYGWIN__ /* Cygwin >= 2.5 */
|
||||
ret = acl_access_nontrivial (acl);
|
||||
saved_errno = errno;
|
||||
acl_free (acl);
|
||||
errno = saved_errno;
|
||||
# else
|
||||
ret = (0 < acl_entries (acl));
|
||||
acl_free (acl);
|
||||
# endif
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
# endif
|
||||
}
|
||||
if (ret < 0)
|
||||
return - acl_errno_valid (errno);
|
||||
return ret;
|
||||
|
||||
# elif HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */
|
||||
|
||||
# if defined ACL_NO_TRIVIAL
|
||||
|
||||
/* Solaris 10 (newer version), which has additional API declared in
|
||||
<sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial,
|
||||
acl_fromtext, ...). */
|
||||
return acl_trivial (name);
|
||||
|
||||
# else /* Solaris, Cygwin, general case */
|
||||
|
||||
/* Solaris 2.5 through Solaris 10, Cygwin, and contemporaneous versions
|
||||
of Unixware. The acl() call returns the access and default ACL both
|
||||
at once. */
|
||||
{
|
||||
/* Initially, try to read the entries into a stack-allocated buffer.
|
||||
Use malloc if it does not fit. */
|
||||
enum
|
||||
{
|
||||
alloc_init = 4000 / sizeof (aclent_t), /* >= 3 */
|
||||
alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (aclent_t))
|
||||
};
|
||||
aclent_t buf[alloc_init];
|
||||
size_t alloc = alloc_init;
|
||||
aclent_t *entries = buf;
|
||||
aclent_t *malloced = NULL;
|
||||
int count;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
count = acl (name, GETACL, alloc, entries);
|
||||
if (count < 0 && errno == ENOSPC)
|
||||
{
|
||||
/* Increase the size of the buffer. */
|
||||
free (malloced);
|
||||
if (alloc > alloc_max / 2)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
alloc = 2 * alloc; /* <= alloc_max */
|
||||
entries = malloced =
|
||||
(aclent_t *) malloc (alloc * sizeof (aclent_t));
|
||||
if (entries == NULL)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (count < 0)
|
||||
{
|
||||
if (errno == ENOSYS || errno == ENOTSUP)
|
||||
;
|
||||
else
|
||||
{
|
||||
free (malloced);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (count == 0)
|
||||
;
|
||||
else
|
||||
{
|
||||
/* Don't use MIN_ACL_ENTRIES: It's set to 4 on Cygwin, but Cygwin
|
||||
returns only 3 entries for files with no ACL. But this is safe:
|
||||
If there are more than 4 entries, there cannot be only the
|
||||
"user::", "group::", "other:", and "mask:" entries. */
|
||||
if (count > 4)
|
||||
{
|
||||
free (malloced);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (acl_nontrivial (count, entries))
|
||||
{
|
||||
free (malloced);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
free (malloced);
|
||||
}
|
||||
|
||||
# ifdef ACE_GETACL
|
||||
/* Solaris also has a different variant of ACLs, used in ZFS and NFSv4
|
||||
file systems (whereas the other ones are used in UFS file systems). */
|
||||
{
|
||||
/* Initially, try to read the entries into a stack-allocated buffer.
|
||||
Use malloc if it does not fit. */
|
||||
enum
|
||||
{
|
||||
alloc_init = 4000 / sizeof (ace_t), /* >= 3 */
|
||||
alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (ace_t))
|
||||
};
|
||||
ace_t buf[alloc_init];
|
||||
size_t alloc = alloc_init;
|
||||
ace_t *entries = buf;
|
||||
ace_t *malloced = NULL;
|
||||
int count;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
count = acl (name, ACE_GETACL, alloc, entries);
|
||||
if (count < 0 && errno == ENOSPC)
|
||||
{
|
||||
/* Increase the size of the buffer. */
|
||||
free (malloced);
|
||||
if (alloc > alloc_max / 2)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
alloc = 2 * alloc; /* <= alloc_max */
|
||||
entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t));
|
||||
if (entries == NULL)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (count < 0)
|
||||
{
|
||||
if (errno == ENOSYS || errno == EINVAL)
|
||||
;
|
||||
else
|
||||
{
|
||||
free (malloced);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (count == 0)
|
||||
;
|
||||
else
|
||||
{
|
||||
/* In the old (original Solaris 10) convention:
|
||||
If there are more than 3 entries, there cannot be only the
|
||||
ACE_OWNER, ACE_GROUP, ACE_OTHER entries.
|
||||
In the newer Solaris 10 and Solaris 11 convention:
|
||||
If there are more than 6 entries, there cannot be only the
|
||||
ACE_OWNER, ACE_GROUP, ACE_EVERYONE entries, each once with
|
||||
NEW_ACE_ACCESS_ALLOWED_ACE_TYPE and once with
|
||||
NEW_ACE_ACCESS_DENIED_ACE_TYPE. */
|
||||
if (count > 6)
|
||||
{
|
||||
free (malloced);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (acl_ace_nontrivial (count, entries))
|
||||
{
|
||||
free (malloced);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
free (malloced);
|
||||
}
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
# endif
|
||||
|
||||
# elif HAVE_GETACL /* HP-UX */
|
||||
|
||||
{
|
||||
struct acl_entry entries[NACLENTRIES];
|
||||
int count;
|
||||
|
||||
count = getacl (name, NACLENTRIES, entries);
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
/* ENOSYS is seen on newer HP-UX versions.
|
||||
EOPNOTSUPP is typically seen on NFS mounts.
|
||||
ENOTSUP was seen on Quantum StorNext file systems (cvfs). */
|
||||
if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
|
||||
;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else if (count == 0)
|
||||
return 0;
|
||||
else /* count > 0 */
|
||||
{
|
||||
if (count > NACLENTRIES)
|
||||
/* If NACLENTRIES cannot be trusted, use dynamic memory
|
||||
allocation. */
|
||||
abort ();
|
||||
|
||||
/* If there are more than 3 entries, there cannot be only the
|
||||
(uid,%), (%,gid), (%,%) entries. */
|
||||
if (count > 3)
|
||||
return 1;
|
||||
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
if (stat (name, &statbuf) == -1 && errno != EOVERFLOW)
|
||||
return -1;
|
||||
|
||||
return acl_nontrivial (count, entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# if HAVE_ACLV_H /* HP-UX >= 11.11 */
|
||||
|
||||
{
|
||||
struct acl entries[NACLVENTRIES];
|
||||
int count;
|
||||
|
||||
count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries);
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
/* EOPNOTSUPP is seen on NFS in HP-UX 11.11, 11.23.
|
||||
EINVAL is seen on NFS in HP-UX 11.31. */
|
||||
if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
|
||||
;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else if (count == 0)
|
||||
return 0;
|
||||
else /* count > 0 */
|
||||
{
|
||||
if (count > NACLVENTRIES)
|
||||
/* If NACLVENTRIES cannot be trusted, use dynamic memory
|
||||
allocation. */
|
||||
abort ();
|
||||
|
||||
/* If there are more than 4 entries, there cannot be only the
|
||||
four base ACL entries. */
|
||||
if (count > 4)
|
||||
return 1;
|
||||
|
||||
return aclv_nontrivial (count, entries);
|
||||
}
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
# elif HAVE_ACLX_GET && defined ACL_AIX_WIP /* AIX */
|
||||
|
||||
acl_type_t type;
|
||||
char aclbuf[1024];
|
||||
void *acl = aclbuf;
|
||||
size_t aclsize = sizeof (aclbuf);
|
||||
mode_t mode;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* The docs say that type being 0 is equivalent to ACL_ANY, but it
|
||||
is not true, in AIX 5.3. */
|
||||
type.u64 = ACL_ANY;
|
||||
if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0)
|
||||
break;
|
||||
if (errno == ENOSYS)
|
||||
return 0;
|
||||
if (errno != ENOSPC)
|
||||
{
|
||||
if (acl != aclbuf)
|
||||
free (acl);
|
||||
return -1;
|
||||
}
|
||||
aclsize = 2 * aclsize;
|
||||
if (acl != aclbuf)
|
||||
free (acl);
|
||||
acl = malloc (aclsize);
|
||||
if (acl == NULL)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (type.u64 == ACL_AIXC)
|
||||
{
|
||||
int result = acl_nontrivial ((struct acl *) acl);
|
||||
if (acl != aclbuf)
|
||||
free (acl);
|
||||
return result;
|
||||
}
|
||||
else if (type.u64 == ACL_NFS4)
|
||||
{
|
||||
int result = acl_nfs4_nontrivial ((nfs4_acl_int_t *) acl);
|
||||
if (acl != aclbuf)
|
||||
free (acl);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A newer type of ACL has been introduced in the system.
|
||||
We should better support it. */
|
||||
if (acl != aclbuf)
|
||||
free (acl);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
# elif HAVE_STATACL /* older AIX */
|
||||
|
||||
union { struct acl a; char room[4096]; } u;
|
||||
|
||||
if (statacl ((char *) name, STX_NORMAL, &u.a, sizeof (u)) < 0)
|
||||
return -1;
|
||||
|
||||
return acl_nontrivial (&u.a);
|
||||
|
||||
# elif HAVE_ACLSORT /* NonStop Kernel */
|
||||
|
||||
{
|
||||
struct acl entries[NACLENTRIES];
|
||||
int count;
|
||||
|
||||
count = acl ((char *) name, ACL_GET, NACLENTRIES, entries);
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
if (errno == ENOSYS || errno == ENOTSUP)
|
||||
;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else if (count == 0)
|
||||
return 0;
|
||||
else /* count > 0 */
|
||||
{
|
||||
if (count > NACLENTRIES)
|
||||
/* If NACLENTRIES cannot be trusted, use dynamic memory
|
||||
allocation. */
|
||||
abort ();
|
||||
|
||||
/* If there are more than 4 entries, there cannot be only the
|
||||
four base ACL entries. */
|
||||
if (count > 4)
|
||||
return 1;
|
||||
|
||||
return acl_nontrivial (count, entries);
|
||||
}
|
||||
}
|
||||
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,166 +0,0 @@
|
|||
/* filemode.c -- make a string describing file modes
|
||||
|
||||
Copyright (C) 1985, 1990, 1993, 1998-2000, 2004, 2006, 2009-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "filemode.h"
|
||||
|
||||
#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) || S_ISMPX (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
|
||||
'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 (S_TYPEISMQ (statp))
|
||||
str[0] = 'Q';
|
||||
else if (S_TYPEISSHM (statp))
|
||||
str[0] = 'S';
|
||||
else if (S_TYPEISTMO (statp))
|
||||
str[0] = 'T';
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/* Make a string describing file modes.
|
||||
|
||||
Copyright (C) 1998-1999, 2003, 2006, 2009-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef FILEMODE_H_
|
||||
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
|
||||
/* Get the declaration of strmode. */
|
||||
# if HAVE_DECL_STRMODE
|
||||
# include <string.h> /* Mac OS X, FreeBSD, OpenBSD */
|
||||
# include <unistd.h> /* NetBSD */
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# if !HAVE_DECL_STRMODE
|
||||
extern void strmode (mode_t mode, char *str);
|
||||
# endif
|
||||
|
||||
extern void filemodestring (struct stat const *statp, char *str);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
|
@ -1,112 +0,0 @@
|
|||
/* Basic filename support macros.
|
||||
Copyright (C) 2001-2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* From Paul Eggert and Jim Meyering. */
|
||||
|
||||
#ifndef _FILENAME_H
|
||||
#define _FILENAME_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Filename support.
|
||||
ISSLASH(C) tests whether C is a directory separator
|
||||
character.
|
||||
HAS_DEVICE(Filename) tests whether Filename contains a device
|
||||
specification.
|
||||
FILE_SYSTEM_PREFIX_LEN(Filename) length of the device specification
|
||||
at the beginning of Filename,
|
||||
index of the part consisting of
|
||||
alternating components and slashes.
|
||||
FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||
1 when a non-empty device specification
|
||||
can be followed by an empty or relative
|
||||
part,
|
||||
0 when a non-empty device specification
|
||||
must be followed by a slash,
|
||||
0 when device specification don't exist.
|
||||
IS_ABSOLUTE_FILE_NAME(Filename)
|
||||
tests whether Filename is independent of
|
||||
any notion of "current directory".
|
||||
IS_RELATIVE_FILE_NAME(Filename)
|
||||
tests whether Filename may be concatenated
|
||||
to a directory filename.
|
||||
Note: On native Windows, OS/2, DOS, "c:" is neither an absolute nor a
|
||||
relative file name!
|
||||
IS_FILE_NAME_WITH_DIR(Filename) tests whether Filename contains a device
|
||||
or directory specification.
|
||||
*/
|
||||
#if defined _WIN32 || defined __CYGWIN__ \
|
||||
|| defined __EMX__ || defined __MSDOS__ || defined __DJGPP__
|
||||
/* Native Windows, Cygwin, OS/2, DOS */
|
||||
# define ISSLASH(C) ((C) == '/' || (C) == '\\')
|
||||
/* Internal macro: Tests whether a character is a drive letter. */
|
||||
# define _IS_DRIVE_LETTER(C) \
|
||||
(((C) >= 'A' && (C) <= 'Z') || ((C) >= 'a' && (C) <= 'z'))
|
||||
/* Help the compiler optimizing it. This assumes ASCII. */
|
||||
# undef _IS_DRIVE_LETTER
|
||||
# define _IS_DRIVE_LETTER(C) \
|
||||
(((unsigned int) (C) | ('a' - 'A')) - 'a' <= 'z' - 'a')
|
||||
# define HAS_DEVICE(Filename) \
|
||||
(_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':')
|
||||
# define FILE_SYSTEM_PREFIX_LEN(Filename) (HAS_DEVICE (Filename) ? 2 : 0)
|
||||
# ifdef __CYGWIN__
|
||||
# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
|
||||
# else
|
||||
/* On native Windows, OS/2, DOS, the system has the notion of a
|
||||
"current directory" on each drive. */
|
||||
# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1
|
||||
# endif
|
||||
# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||
# define IS_ABSOLUTE_FILE_NAME(Filename) \
|
||||
ISSLASH ((Filename)[FILE_SYSTEM_PREFIX_LEN (Filename)])
|
||||
# else
|
||||
# define IS_ABSOLUTE_FILE_NAME(Filename) \
|
||||
(ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename))
|
||||
# endif
|
||||
# define IS_RELATIVE_FILE_NAME(Filename) \
|
||||
(! (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename)))
|
||||
# define IS_FILE_NAME_WITH_DIR(Filename) \
|
||||
(strchr ((Filename), '/') != NULL || strchr ((Filename), '\\') != NULL \
|
||||
|| HAS_DEVICE (Filename))
|
||||
#else
|
||||
/* Unix */
|
||||
# define ISSLASH(C) ((C) == '/')
|
||||
# define HAS_DEVICE(Filename) ((void) (Filename), 0)
|
||||
# define FILE_SYSTEM_PREFIX_LEN(Filename) ((void) (Filename), 0)
|
||||
# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
|
||||
# define IS_ABSOLUTE_FILE_NAME(Filename) ISSLASH ((Filename)[0])
|
||||
# define IS_RELATIVE_FILE_NAME(Filename) (! ISSLASH ((Filename)[0]))
|
||||
# define IS_FILE_NAME_WITH_DIR(Filename) (strchr ((Filename), '/') != NULL)
|
||||
#endif
|
||||
|
||||
/* Deprecated macros. For backward compatibility with old users of the
|
||||
'filename' module. */
|
||||
#define IS_ABSOLUTE_PATH IS_ABSOLUTE_FILE_NAME
|
||||
#define IS_PATH_WITH_DIR IS_FILE_NAME_WITH_DIR
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FILENAME_H */
|
|
@ -1,188 +0,0 @@
|
|||
/* Compare file names containing version numbers.
|
||||
|
||||
Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
|
||||
Copyright (C) 2001 Anthony Towns <aj@azure.humbug.org.au>
|
||||
Copyright (C) 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include "filevercmp.h"
|
||||
|
||||
#include <c-ctype.h>
|
||||
#include <limits.h>
|
||||
#include <idx.h>
|
||||
|
||||
/* Return the length of a prefix of S that corresponds to the suffix
|
||||
defined by this extended regular expression in the C locale:
|
||||
(\.[A-Za-z~][A-Za-z0-9~]*)*$
|
||||
Use the longest suffix matching this regular expression,
|
||||
except do not use all of S as a suffix if S is nonempty.
|
||||
If *LEN is -1, S is a string; set *LEN to S's length.
|
||||
Otherwise, *LEN should be nonnegative, S is a char array,
|
||||
and *LEN does not change. */
|
||||
static idx_t
|
||||
file_prefixlen (char const *s, ptrdiff_t *len)
|
||||
{
|
||||
size_t n = *len; /* SIZE_MAX if N == -1. */
|
||||
idx_t prefixlen = 0;
|
||||
|
||||
for (idx_t i = 0; ; )
|
||||
{
|
||||
if (*len < 0 ? !s[i] : i == n)
|
||||
{
|
||||
*len = i;
|
||||
return prefixlen;
|
||||
}
|
||||
|
||||
i++;
|
||||
prefixlen = i;
|
||||
while (i + 1 < n && s[i] == '.' && (c_isalpha (s[i + 1])
|
||||
|| s[i + 1] == '~'))
|
||||
for (i += 2; i < n && (c_isalnum (s[i]) || s[i] == '~'); i++)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a version sort comparison value for S's byte at position POS.
|
||||
S has length LEN. If POS == LEN, sort before all non-'~' bytes. */
|
||||
|
||||
static int
|
||||
order (char const *s, idx_t pos, idx_t len)
|
||||
{
|
||||
if (pos == len)
|
||||
return -1;
|
||||
|
||||
unsigned char c = s[pos];
|
||||
if (c_isdigit (c))
|
||||
return 0;
|
||||
else if (c_isalpha (c))
|
||||
return c;
|
||||
else if (c == '~')
|
||||
return -2;
|
||||
else
|
||||
{
|
||||
static_assert (UCHAR_MAX <= (INT_MAX - 1 - 2) / 2);
|
||||
return c + UCHAR_MAX + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* slightly modified verrevcmp function from dpkg
|
||||
S1, S2 - compared char array
|
||||
S1_LEN, S2_LEN - length of arrays to be scanned
|
||||
|
||||
This implements the algorithm for comparison of version strings
|
||||
specified by Debian and now widely adopted. The detailed
|
||||
specification can be found in the Debian Policy Manual in the
|
||||
section on the 'Version' control field. This version of the code
|
||||
implements that from s5.6.12 of Debian Policy v3.8.0.1
|
||||
https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version */
|
||||
static int _GL_ATTRIBUTE_PURE
|
||||
verrevcmp (const char *s1, idx_t s1_len, const char *s2, idx_t s2_len)
|
||||
{
|
||||
idx_t s1_pos = 0;
|
||||
idx_t s2_pos = 0;
|
||||
while (s1_pos < s1_len || s2_pos < s2_len)
|
||||
{
|
||||
int first_diff = 0;
|
||||
while ((s1_pos < s1_len && !c_isdigit (s1[s1_pos]))
|
||||
|| (s2_pos < s2_len && !c_isdigit (s2[s2_pos])))
|
||||
{
|
||||
int s1_c = order (s1, s1_pos, s1_len);
|
||||
int s2_c = order (s2, s2_pos, s2_len);
|
||||
if (s1_c != s2_c)
|
||||
return s1_c - s2_c;
|
||||
s1_pos++;
|
||||
s2_pos++;
|
||||
}
|
||||
while (s1_pos < s1_len && s1[s1_pos] == '0')
|
||||
s1_pos++;
|
||||
while (s2_pos < s2_len && s2[s2_pos] == '0')
|
||||
s2_pos++;
|
||||
while (s1_pos < s1_len && s2_pos < s2_len
|
||||
&& c_isdigit (s1[s1_pos]) && c_isdigit (s2[s2_pos]))
|
||||
{
|
||||
if (!first_diff)
|
||||
first_diff = s1[s1_pos] - s2[s2_pos];
|
||||
s1_pos++;
|
||||
s2_pos++;
|
||||
}
|
||||
if (s1_pos < s1_len && c_isdigit (s1[s1_pos]))
|
||||
return 1;
|
||||
if (s2_pos < s2_len && c_isdigit (s2[s2_pos]))
|
||||
return -1;
|
||||
if (first_diff)
|
||||
return first_diff;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compare version strings S1 and S2.
|
||||
See filevercmp.h for function description. */
|
||||
int
|
||||
filevercmp (const char *s1, const char *s2)
|
||||
{
|
||||
return filenvercmp (s1, -1, s2, -1);
|
||||
}
|
||||
|
||||
/* Compare versions A (of length ALEN) and B (of length BLEN).
|
||||
See filevercmp.h for function description. */
|
||||
int
|
||||
filenvercmp (char const *a, ptrdiff_t alen, char const *b, ptrdiff_t blen)
|
||||
{
|
||||
/* Special case for empty versions. */
|
||||
bool aempty = alen < 0 ? !a[0] : !alen;
|
||||
bool bempty = blen < 0 ? !b[0] : !blen;
|
||||
if (aempty)
|
||||
return -!bempty;
|
||||
if (bempty)
|
||||
return 1;
|
||||
|
||||
/* Special cases for leading ".": "." sorts first, then "..", then
|
||||
other names with leading ".", then other names. */
|
||||
if (a[0] == '.')
|
||||
{
|
||||
if (b[0] != '.')
|
||||
return -1;
|
||||
|
||||
bool adot = alen < 0 ? !a[1] : alen == 1;
|
||||
bool bdot = blen < 0 ? !b[1] : blen == 1;
|
||||
if (adot)
|
||||
return -!bdot;
|
||||
if (bdot)
|
||||
return 1;
|
||||
|
||||
bool adotdot = a[1] == '.' && (alen < 0 ? !a[2] : alen == 2);
|
||||
bool bdotdot = b[1] == '.' && (blen < 0 ? !b[2] : blen == 2);
|
||||
if (adotdot)
|
||||
return -!bdotdot;
|
||||
if (bdotdot)
|
||||
return 1;
|
||||
}
|
||||
else if (b[0] == '.')
|
||||
return 1;
|
||||
|
||||
/* Cut file suffixes. */
|
||||
idx_t aprefixlen = file_prefixlen (a, &alen);
|
||||
idx_t bprefixlen = file_prefixlen (b, &blen);
|
||||
|
||||
/* If both suffixes are empty, a second pass would return the same thing. */
|
||||
bool one_pass_only = aprefixlen == alen && bprefixlen == blen;
|
||||
|
||||
int result = verrevcmp (a, aprefixlen, b, bprefixlen);
|
||||
|
||||
/* Return the initial result if nonzero, or if no second pass is needed.
|
||||
Otherwise, restore the suffixes and try again. */
|
||||
return result || one_pass_only ? result : verrevcmp (a, alen, b, blen);
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/* Compare file names containing version numbers.
|
||||
|
||||
Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
|
||||
Copyright (C) 2001 Anthony Towns <aj@azure.humbug.org.au>
|
||||
Copyright (C) 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef FILEVERCMP_H
|
||||
#define FILEVERCMP_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* Compare strings A and B as file names containing version numbers,
|
||||
and return an integer that is negative, zero, or positive depending
|
||||
on whether A compares less than, equal to, or greater than B.
|
||||
|
||||
Use the following version sort algorithm:
|
||||
|
||||
1. Compare the strings' maximal-length non-digit prefixes lexically.
|
||||
If there is a difference return that difference.
|
||||
Otherwise discard the prefixes and continue with the next step.
|
||||
|
||||
2. Compare the strings' maximal-length digit prefixes, using
|
||||
numeric comparison of the numbers represented by each prefix.
|
||||
(Treat an empty prefix as zero; this can happen only at string end.)
|
||||
If there is a difference, return that difference.
|
||||
Otherwise discard the prefixes and continue with the next step.
|
||||
|
||||
3. If both strings are empty, return 0. Otherwise continue with step 1.
|
||||
|
||||
In version sort, lexical comparison is left to right, byte by byte,
|
||||
using the byte's numeric value (0-255), except that:
|
||||
|
||||
1. ASCII letters sort before other bytes.
|
||||
2. A tilde sorts before anything, even an empty string.
|
||||
|
||||
In addition to the version sort rules, the following strings have
|
||||
special priority and sort before all other strings (listed in order):
|
||||
|
||||
1. The empty string.
|
||||
2. ".".
|
||||
3. "..".
|
||||
4. Strings starting with "." sort before other strings.
|
||||
|
||||
Before comparing two strings where both begin with non-".",
|
||||
or where both begin with "." but neither is "." or "..",
|
||||
suffixes matching the C-locale extended regular expression
|
||||
(\.[A-Za-z~][A-Za-z0-9~]*)*$ are removed and the strings compared
|
||||
without them, using version sort without special priority;
|
||||
if they do not compare equal, this comparison result is used and
|
||||
the suffixes are effectively ignored. Otherwise, the entire
|
||||
strings are compared using version sort. When removing a suffix
|
||||
from a nonempty string, remove the maximal-length suffix such that
|
||||
the remaining string is nonempty.
|
||||
|
||||
This function is intended to be a replacement for strverscmp. */
|
||||
int filevercmp (char const *a, char const *b) _GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Like filevercmp, except compare the byte arrays A (of length ALEN)
|
||||
and B (of length BLEN) so that A and B can contain '\0', which
|
||||
sorts just before '\1'. But if ALEN is -1 treat A as a string
|
||||
terminated by '\0', and similarly for BLEN. */
|
||||
int filenvercmp (char const *a, ptrdiff_t alen, char const *b, ptrdiff_t blen)
|
||||
_GL_ATTRIBUTE_PURE;
|
||||
|
||||
#endif /* FILEVERCMP_H */
|
|
@ -1,66 +0,0 @@
|
|||
/* Placeholder fingerprint for Emacs
|
||||
|
||||
Copyright 2019-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "fingerprint.h"
|
||||
|
||||
/* This random fingerprint was generated by the shell command:
|
||||
|
||||
shuf -i 0-255 -n 32 -r | awk '{printf " 0x%.02X,\n", $0}'
|
||||
|
||||
In the final Emacs executable, this random fingerprint is replaced
|
||||
by a fingerprint of the temporary Emacs executable that was built
|
||||
along the way. */
|
||||
|
||||
volatile unsigned char fingerprint[] =
|
||||
{
|
||||
0xDE,
|
||||
0x86,
|
||||
0xBB,
|
||||
0x99,
|
||||
0xFF,
|
||||
0xF5,
|
||||
0x46,
|
||||
0x9A,
|
||||
0x9E,
|
||||
0x3F,
|
||||
0x9F,
|
||||
0x5D,
|
||||
0x9A,
|
||||
0xDF,
|
||||
0xF0,
|
||||
0x91,
|
||||
0xBD,
|
||||
0xCD,
|
||||
0xC1,
|
||||
0xE8,
|
||||
0x0C,
|
||||
0x16,
|
||||
0x1E,
|
||||
0xAF,
|
||||
0xB8,
|
||||
0x6C,
|
||||
0xE2,
|
||||
0x2B,
|
||||
0xB1,
|
||||
0x24,
|
||||
0xCE,
|
||||
0xB0,
|
||||
};
|
|
@ -1,28 +0,0 @@
|
|||
/* Header file for the Emacs build fingerprint.
|
||||
|
||||
Copyright (C) 2016, 2018-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef EMACS_FINGERPRINT_H
|
||||
#define EMACS_FINGERPRINT_H
|
||||
|
||||
/* We generate fingerprint.c and fingerprint.o from all the sources in
|
||||
Emacs. This way, we have a unique value that we can use to pair
|
||||
data files (like a dump file) with a specific build of Emacs. */
|
||||
extern volatile unsigned char fingerprint[32];
|
||||
|
||||
#endif
|
|
@ -1,60 +0,0 @@
|
|||
/* Sizes of structs with flexible array members.
|
||||
|
||||
Copyright 2016-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below.
|
||||
On older platforms without _Alignof, use a pessimistic bound that is
|
||||
safe in practice even if FLEXIBLE_ARRAY_MEMBER is 1.
|
||||
On newer platforms, use _Alignof to get a tighter bound. */
|
||||
|
||||
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
|
||||
# define FLEXALIGNOF(type) (sizeof (type) & ~ (sizeof (type) - 1))
|
||||
#else
|
||||
# define FLEXALIGNOF(type) _Alignof (type)
|
||||
#endif
|
||||
|
||||
/* Yield a properly aligned upper bound on the size of a struct of
|
||||
type TYPE with a flexible array member named MEMBER that is
|
||||
followed by N bytes of other data. The result is suitable as an
|
||||
argument to malloc. For example:
|
||||
|
||||
struct s { int n; char d[FLEXIBLE_ARRAY_MEMBER]; };
|
||||
struct s *p = malloc (FLEXSIZEOF (struct s, d, n * sizeof (char)));
|
||||
|
||||
FLEXSIZEOF (TYPE, MEMBER, N) is not simply (sizeof (TYPE) + N),
|
||||
since FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms. Nor is
|
||||
it simply (offsetof (TYPE, MEMBER) + N), as that might yield a size
|
||||
that causes malloc to yield a pointer that is not properly aligned
|
||||
for TYPE; for example, if sizeof (int) == alignof (int) == 4,
|
||||
malloc (offsetof (struct s, d) + 3 * sizeof (char)) is equivalent
|
||||
to malloc (7) and might yield a pointer that is not a multiple of 4
|
||||
(which means the pointer is not properly aligned for struct s),
|
||||
whereas malloc (FLEXSIZEOF (struct s, d, 3 * sizeof (char))) is
|
||||
equivalent to malloc (8) and must yield a pointer that is a
|
||||
multiple of 4.
|
||||
|
||||
Yield a value less than N if and only if arithmetic overflow occurs. */
|
||||
|
||||
#define FLEXSIZEOF(type, member, n) \
|
||||
((offsetof (type, member) + FLEXALIGNOF (type) - 1 + (n)) \
|
||||
& ~ (FLEXALIGNOF (type) - 1))
|
|
@ -1,147 +0,0 @@
|
|||
/* Supplemental information about the floating-point formats.
|
||||
Copyright (C) 2007, 2009-2023 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2007.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _FLOATPLUS_H
|
||||
#define _FLOATPLUS_H
|
||||
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* Number of bits in the mantissa of a floating-point number, including the
|
||||
"hidden bit". */
|
||||
#if FLT_RADIX == 2
|
||||
# define FLT_MANT_BIT FLT_MANT_DIG
|
||||
# define DBL_MANT_BIT DBL_MANT_DIG
|
||||
# define LDBL_MANT_BIT LDBL_MANT_DIG
|
||||
#elif FLT_RADIX == 4
|
||||
# define FLT_MANT_BIT (FLT_MANT_DIG * 2)
|
||||
# define DBL_MANT_BIT (DBL_MANT_DIG * 2)
|
||||
# define LDBL_MANT_BIT (LDBL_MANT_DIG * 2)
|
||||
#elif FLT_RADIX == 16
|
||||
# define FLT_MANT_BIT (FLT_MANT_DIG * 4)
|
||||
# define DBL_MANT_BIT (DBL_MANT_DIG * 4)
|
||||
# define LDBL_MANT_BIT (LDBL_MANT_DIG * 4)
|
||||
#endif
|
||||
|
||||
/* Bit mask that can be used to mask the exponent, as an unsigned number. */
|
||||
#define FLT_EXP_MASK ((FLT_MAX_EXP - FLT_MIN_EXP) | 7)
|
||||
#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
|
||||
#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7)
|
||||
|
||||
/* Number of bits used for the exponent of a floating-point number, including
|
||||
the exponent's sign. */
|
||||
#define FLT_EXP_BIT \
|
||||
(FLT_EXP_MASK < 0x100 ? 8 : \
|
||||
FLT_EXP_MASK < 0x200 ? 9 : \
|
||||
FLT_EXP_MASK < 0x400 ? 10 : \
|
||||
FLT_EXP_MASK < 0x800 ? 11 : \
|
||||
FLT_EXP_MASK < 0x1000 ? 12 : \
|
||||
FLT_EXP_MASK < 0x2000 ? 13 : \
|
||||
FLT_EXP_MASK < 0x4000 ? 14 : \
|
||||
FLT_EXP_MASK < 0x8000 ? 15 : \
|
||||
FLT_EXP_MASK < 0x10000 ? 16 : \
|
||||
FLT_EXP_MASK < 0x20000 ? 17 : \
|
||||
FLT_EXP_MASK < 0x40000 ? 18 : \
|
||||
FLT_EXP_MASK < 0x80000 ? 19 : \
|
||||
FLT_EXP_MASK < 0x100000 ? 20 : \
|
||||
FLT_EXP_MASK < 0x200000 ? 21 : \
|
||||
FLT_EXP_MASK < 0x400000 ? 22 : \
|
||||
FLT_EXP_MASK < 0x800000 ? 23 : \
|
||||
FLT_EXP_MASK < 0x1000000 ? 24 : \
|
||||
FLT_EXP_MASK < 0x2000000 ? 25 : \
|
||||
FLT_EXP_MASK < 0x4000000 ? 26 : \
|
||||
FLT_EXP_MASK < 0x8000000 ? 27 : \
|
||||
FLT_EXP_MASK < 0x10000000 ? 28 : \
|
||||
FLT_EXP_MASK < 0x20000000 ? 29 : \
|
||||
FLT_EXP_MASK < 0x40000000 ? 30 : \
|
||||
FLT_EXP_MASK <= 0x7fffffff ? 31 : \
|
||||
32)
|
||||
#define DBL_EXP_BIT \
|
||||
(DBL_EXP_MASK < 0x100 ? 8 : \
|
||||
DBL_EXP_MASK < 0x200 ? 9 : \
|
||||
DBL_EXP_MASK < 0x400 ? 10 : \
|
||||
DBL_EXP_MASK < 0x800 ? 11 : \
|
||||
DBL_EXP_MASK < 0x1000 ? 12 : \
|
||||
DBL_EXP_MASK < 0x2000 ? 13 : \
|
||||
DBL_EXP_MASK < 0x4000 ? 14 : \
|
||||
DBL_EXP_MASK < 0x8000 ? 15 : \
|
||||
DBL_EXP_MASK < 0x10000 ? 16 : \
|
||||
DBL_EXP_MASK < 0x20000 ? 17 : \
|
||||
DBL_EXP_MASK < 0x40000 ? 18 : \
|
||||
DBL_EXP_MASK < 0x80000 ? 19 : \
|
||||
DBL_EXP_MASK < 0x100000 ? 20 : \
|
||||
DBL_EXP_MASK < 0x200000 ? 21 : \
|
||||
DBL_EXP_MASK < 0x400000 ? 22 : \
|
||||
DBL_EXP_MASK < 0x800000 ? 23 : \
|
||||
DBL_EXP_MASK < 0x1000000 ? 24 : \
|
||||
DBL_EXP_MASK < 0x2000000 ? 25 : \
|
||||
DBL_EXP_MASK < 0x4000000 ? 26 : \
|
||||
DBL_EXP_MASK < 0x8000000 ? 27 : \
|
||||
DBL_EXP_MASK < 0x10000000 ? 28 : \
|
||||
DBL_EXP_MASK < 0x20000000 ? 29 : \
|
||||
DBL_EXP_MASK < 0x40000000 ? 30 : \
|
||||
DBL_EXP_MASK <= 0x7fffffff ? 31 : \
|
||||
32)
|
||||
#define LDBL_EXP_BIT \
|
||||
(LDBL_EXP_MASK < 0x100 ? 8 : \
|
||||
LDBL_EXP_MASK < 0x200 ? 9 : \
|
||||
LDBL_EXP_MASK < 0x400 ? 10 : \
|
||||
LDBL_EXP_MASK < 0x800 ? 11 : \
|
||||
LDBL_EXP_MASK < 0x1000 ? 12 : \
|
||||
LDBL_EXP_MASK < 0x2000 ? 13 : \
|
||||
LDBL_EXP_MASK < 0x4000 ? 14 : \
|
||||
LDBL_EXP_MASK < 0x8000 ? 15 : \
|
||||
LDBL_EXP_MASK < 0x10000 ? 16 : \
|
||||
LDBL_EXP_MASK < 0x20000 ? 17 : \
|
||||
LDBL_EXP_MASK < 0x40000 ? 18 : \
|
||||
LDBL_EXP_MASK < 0x80000 ? 19 : \
|
||||
LDBL_EXP_MASK < 0x100000 ? 20 : \
|
||||
LDBL_EXP_MASK < 0x200000 ? 21 : \
|
||||
LDBL_EXP_MASK < 0x400000 ? 22 : \
|
||||
LDBL_EXP_MASK < 0x800000 ? 23 : \
|
||||
LDBL_EXP_MASK < 0x1000000 ? 24 : \
|
||||
LDBL_EXP_MASK < 0x2000000 ? 25 : \
|
||||
LDBL_EXP_MASK < 0x4000000 ? 26 : \
|
||||
LDBL_EXP_MASK < 0x8000000 ? 27 : \
|
||||
LDBL_EXP_MASK < 0x10000000 ? 28 : \
|
||||
LDBL_EXP_MASK < 0x20000000 ? 29 : \
|
||||
LDBL_EXP_MASK < 0x40000000 ? 30 : \
|
||||
LDBL_EXP_MASK <= 0x7fffffff ? 31 : \
|
||||
32)
|
||||
|
||||
/* Number of bits used for a floating-point number: the mantissa (not
|
||||
counting the "hidden bit", since it may or may not be explicit), the
|
||||
exponent, and the sign. */
|
||||
#define FLT_TOTAL_BIT ((FLT_MANT_BIT - 1) + FLT_EXP_BIT + 1)
|
||||
#define DBL_TOTAL_BIT ((DBL_MANT_BIT - 1) + DBL_EXP_BIT + 1)
|
||||
#define LDBL_TOTAL_BIT ((LDBL_MANT_BIT - 1) + LDBL_EXP_BIT + 1)
|
||||
|
||||
/* Number of bytes used for a floating-point number.
|
||||
This can be smaller than the 'sizeof'. For example, on i386 systems,
|
||||
'long double' most often have LDBL_MANT_BIT = 64, LDBL_EXP_BIT = 16, hence
|
||||
LDBL_TOTAL_BIT = 80 bits, i.e. 10 bytes of consecutive memory, but
|
||||
sizeof (long double) = 12 or = 16. */
|
||||
#define SIZEOF_FLT ((FLT_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
|
||||
#define SIZEOF_DBL ((DBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
|
||||
#define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
|
||||
|
||||
/* Verify that SIZEOF_FLT <= sizeof (float) etc. */
|
||||
typedef int verify_sizeof_flt[SIZEOF_FLT <= sizeof (float) ? 1 : -1];
|
||||
typedef int verify_sizeof_dbl[SIZEOF_DBL <= sizeof (double) ? 1 : - 1];
|
||||
typedef int verify_sizeof_ldbl[SIZEOF_LDBL <= sizeof (long double) ? 1 : - 1];
|
||||
|
||||
#endif /* _FLOATPLUS_H */
|
|
@ -1,33 +0,0 @@
|
|||
/* Auxiliary definitions for <float.h>.
|
||||
Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2011.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <float.h>
|
||||
|
||||
#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__
|
||||
const union gl_long_double_union gl_LDBL_MAX =
|
||||
{ { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL } };
|
||||
#elif defined __i386__
|
||||
const union gl_long_double_union gl_LDBL_MAX =
|
||||
{ { 0xFFFFFFFF, 0xFFFFFFFF, 32766 } };
|
||||
#else
|
||||
/* This declaration is solely to ensure that after preprocessing
|
||||
this file is never empty. */
|
||||
typedef int dummy;
|
||||
#endif
|
|
@ -1,194 +0,0 @@
|
|||
/* A correct <float.h>.
|
||||
|
||||
Copyright (C) 2007-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_FLOAT_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#@INCLUDE_NEXT@ @NEXT_FLOAT_H@
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_FLOAT_H
|
||||
#define _@GUARD_PREFIX@_FLOAT_H
|
||||
|
||||
/* 'long double' properties. */
|
||||
|
||||
#if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__)
|
||||
/* Number of mantissa units, in base FLT_RADIX. */
|
||||
# undef LDBL_MANT_DIG
|
||||
# define LDBL_MANT_DIG 64
|
||||
/* Number of decimal digits that is sufficient for representing a number. */
|
||||
# undef LDBL_DIG
|
||||
# define LDBL_DIG 18
|
||||
/* x-1 where x is the smallest representable number > 1. */
|
||||
# undef LDBL_EPSILON
|
||||
# define LDBL_EPSILON 1.0842021724855044340E-19L
|
||||
/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */
|
||||
# undef LDBL_MIN_EXP
|
||||
# define LDBL_MIN_EXP (-16381)
|
||||
/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */
|
||||
# undef LDBL_MAX_EXP
|
||||
# define LDBL_MAX_EXP 16384
|
||||
/* Minimum positive normalized number. */
|
||||
# undef LDBL_MIN
|
||||
# define LDBL_MIN 3.3621031431120935063E-4932L
|
||||
/* Maximum representable finite number. */
|
||||
# undef LDBL_MAX
|
||||
# define LDBL_MAX 1.1897314953572317650E+4932L
|
||||
/* Minimum e such that 10^e is in the range of normalized numbers. */
|
||||
# undef LDBL_MIN_10_EXP
|
||||
# define LDBL_MIN_10_EXP (-4931)
|
||||
/* Maximum e such that 10^e is in the range of representable finite numbers. */
|
||||
# undef LDBL_MAX_10_EXP
|
||||
# define LDBL_MAX_10_EXP 4932
|
||||
#endif
|
||||
|
||||
/* On FreeBSD/x86 6.4, the 'long double' type really has only 53 bits of
|
||||
precision in the compiler but 64 bits of precision at runtime. See
|
||||
<https://lists.gnu.org/r/bug-gnulib/2008-07/msg00063.html>. */
|
||||
#if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__)
|
||||
/* Number of mantissa units, in base FLT_RADIX. */
|
||||
# undef LDBL_MANT_DIG
|
||||
# define LDBL_MANT_DIG 64
|
||||
/* Number of decimal digits that is sufficient for representing a number. */
|
||||
# undef LDBL_DIG
|
||||
# define LDBL_DIG 18
|
||||
/* x-1 where x is the smallest representable number > 1. */
|
||||
# undef LDBL_EPSILON
|
||||
# define LDBL_EPSILON 1.084202172485504434007452800869941711426e-19L /* 2^-63 */
|
||||
/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */
|
||||
# undef LDBL_MIN_EXP
|
||||
# define LDBL_MIN_EXP (-16381)
|
||||
/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */
|
||||
# undef LDBL_MAX_EXP
|
||||
# define LDBL_MAX_EXP 16384
|
||||
/* Minimum positive normalized number. */
|
||||
# undef LDBL_MIN
|
||||
# define LDBL_MIN 3.362103143112093506262677817321752E-4932L /* = 0x1p-16382L */
|
||||
/* Maximum representable finite number. */
|
||||
# undef LDBL_MAX
|
||||
/* LDBL_MAX is represented as { 0xFFFFFFFF, 0xFFFFFFFF, 32766 }.
|
||||
But the largest literal that GCC allows us to write is
|
||||
0x0.fffffffffffff8p16384L = { 0xFFFFF800, 0xFFFFFFFF, 32766 }.
|
||||
So, define it like this through a reference to an external variable
|
||||
|
||||
const unsigned int LDBL_MAX[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 32766 };
|
||||
extern const long double LDBL_MAX;
|
||||
|
||||
Unfortunately, this is not a constant expression. */
|
||||
# if !GNULIB_defined_long_double_union
|
||||
union gl_long_double_union
|
||||
{
|
||||
struct { unsigned int lo; unsigned int hi; unsigned int exponent; } xd;
|
||||
long double ld;
|
||||
};
|
||||
# define GNULIB_defined_long_double_union 1
|
||||
# endif
|
||||
extern const union gl_long_double_union gl_LDBL_MAX;
|
||||
# define LDBL_MAX (gl_LDBL_MAX.ld)
|
||||
/* Minimum e such that 10^e is in the range of normalized numbers. */
|
||||
# undef LDBL_MIN_10_EXP
|
||||
# define LDBL_MIN_10_EXP (-4931)
|
||||
/* Maximum e such that 10^e is in the range of representable finite numbers. */
|
||||
# undef LDBL_MAX_10_EXP
|
||||
# define LDBL_MAX_10_EXP 4932
|
||||
#endif
|
||||
|
||||
/* On AIX 7.1 with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX are
|
||||
wrong.
|
||||
On Linux/PowerPC with gcc 4.4, the value of LDBL_MAX is wrong. */
|
||||
#if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__
|
||||
# undef LDBL_MIN_EXP
|
||||
# define LDBL_MIN_EXP DBL_MIN_EXP
|
||||
# undef LDBL_MIN_10_EXP
|
||||
# define LDBL_MIN_10_EXP DBL_MIN_10_EXP
|
||||
# undef LDBL_MIN
|
||||
# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */
|
||||
#endif
|
||||
#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__
|
||||
# undef LDBL_MAX
|
||||
/* LDBL_MAX is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xFFFFFFFF }.
|
||||
It is not easy to define:
|
||||
#define LDBL_MAX 1.79769313486231580793728971405302307166e308L
|
||||
is too small, whereas
|
||||
#define LDBL_MAX 1.79769313486231580793728971405302307167e308L
|
||||
is too large. Apparently a bug in GCC decimal-to-binary conversion.
|
||||
Also, I can't get values larger than
|
||||
#define LDBL63 ((long double) (1ULL << 63))
|
||||
#define LDBL882 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63)
|
||||
#define LDBL945 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63)
|
||||
#define LDBL1008 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63)
|
||||
#define LDBL_MAX (LDBL1008 * 65535.0L + LDBL945 * (long double) 9223372036821221375ULL + LDBL882 * (long double) 4611686018427387904ULL)
|
||||
which is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xF8000000 }.
|
||||
So, define it like this through a reference to an external variable
|
||||
|
||||
const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL };
|
||||
extern const long double LDBL_MAX;
|
||||
|
||||
or through a pointer cast
|
||||
|
||||
#define LDBL_MAX \
|
||||
(*(const long double *) (double[]) { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL })
|
||||
|
||||
Unfortunately, this is not a constant expression, and the latter expression
|
||||
does not work well when GCC is optimizing.. */
|
||||
# if !GNULIB_defined_long_double_union
|
||||
union gl_long_double_union
|
||||
{
|
||||
struct { double hi; double lo; } dd;
|
||||
long double ld;
|
||||
};
|
||||
# define GNULIB_defined_long_double_union 1
|
||||
# endif
|
||||
extern const union gl_long_double_union gl_LDBL_MAX;
|
||||
# define LDBL_MAX (gl_LDBL_MAX.ld)
|
||||
#endif
|
||||
|
||||
/* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong.
|
||||
On IRIX 6.5, with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_EPSILON
|
||||
are wrong. */
|
||||
#if defined __sgi && (LDBL_MANT_DIG >= 106)
|
||||
# undef LDBL_MANT_DIG
|
||||
# define LDBL_MANT_DIG 106
|
||||
# if defined __GNUC__
|
||||
# undef LDBL_MIN_EXP
|
||||
# define LDBL_MIN_EXP DBL_MIN_EXP
|
||||
# undef LDBL_MIN_10_EXP
|
||||
# define LDBL_MIN_10_EXP DBL_MIN_10_EXP
|
||||
# undef LDBL_MIN
|
||||
# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */
|
||||
# undef LDBL_EPSILON
|
||||
# define LDBL_EPSILON 2.46519032881566189191165176650870696773e-32L /* 2^-105 */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @REPLACE_ITOLD@
|
||||
/* Pull in a function that fixes the 'int' to 'long double' conversion
|
||||
of glibc 2.7. */
|
||||
extern
|
||||
# ifdef __cplusplus
|
||||
"C"
|
||||
# endif
|
||||
void _Qp_itoq (long double *, int);
|
||||
static void (*_gl_float_fix_itold) (long double *, int) = _Qp_itoq;
|
||||
#endif
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_FLOAT_H */
|
||||
#endif /* _@GUARD_PREFIX@_FLOAT_H */
|
|
@ -1,63 +0,0 @@
|
|||
/* fpending.c -- return the number of pending output bytes on a stream
|
||||
Copyright (C) 2000, 2004, 2006-2007, 2009-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Jim Meyering. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "fpending.h"
|
||||
|
||||
#include "stdio-impl.h"
|
||||
|
||||
/* This file is not used on systems that already have the __fpending function,
|
||||
namely glibc >= 2.2, Solaris >= 7, UnixWare >= 7.1.4.MP4, Cygwin >= 1.7.34,
|
||||
Android API >= 23. */
|
||||
|
||||
/* Return the number of pending (aka buffered, unflushed)
|
||||
bytes on the stream, FP, that is open for writing. */
|
||||
size_t
|
||||
__fpending (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_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
|
||||
/* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
return fp->_IO_write_ptr - fp->_IO_write_base;
|
||||
#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
|
||||
/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin < 1.7.34, Minix 3, Android */
|
||||
return fp_->_p - fp_->_bf._base;
|
||||
#elif defined __EMX__ /* emx+gcc */
|
||||
return fp->_ptr - fp->_buffer;
|
||||
#elif defined __minix /* Minix */
|
||||
return fp_->_ptr - fp_->_buf;
|
||||
#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */
|
||||
return (fp_->_ptr ? fp_->_ptr - fp_->_base : 0);
|
||||
#elif defined __UCLIBC__ /* uClibc */
|
||||
return (fp->__modeflags & __FLAG_WRITING ? fp->__bufpos - fp->__bufstart : 0);
|
||||
#elif defined __QNX__ /* QNX */
|
||||
return (fp->_Mode & 0x2000 /*_MWRITE*/ ? fp->_Next - fp->_Buf : 0);
|
||||
#elif defined __MINT__ /* Atari FreeMiNT */
|
||||
return fp->__bufp - fp->__buffer;
|
||||
#elif defined EPLAN9 /* Plan9 */
|
||||
return fp->wp - fp->buf;
|
||||
#else
|
||||
# error "Please port gnulib fpending.c to your platform!"
|
||||
return 1;
|
||||
#endif
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/* Declare __fpending.
|
||||
|
||||
Copyright (C) 2000, 2003, 2005-2006, 2009-2023 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Jim Meyering. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#if HAVE_STDIO_EXT_H
|
||||
# include <stdio_ext.h>
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL___FPENDING
|
||||
size_t __fpending (FILE *) _GL_ATTRIBUTE_PURE;
|
||||
#endif
|
|
@ -1,108 +0,0 @@
|
|||
/* Manipulating the FPU control word. -*- coding: utf-8 -*-
|
||||
Copyright (C) 2007-2023 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2007.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _FPUCW_H
|
||||
#define _FPUCW_H
|
||||
|
||||
/* The i386 floating point hardware (the 387 compatible FPU, not the modern
|
||||
SSE/SSE2 hardware) has a controllable rounding precision. It is specified
|
||||
through the 'PC' bits in the FPU control word ('fctrl' register). (See
|
||||
the GNU libc i386 <fpu_control.h> header for details.)
|
||||
|
||||
On some platforms, such as Linux or Solaris, the default precision setting
|
||||
is set to "extended precision". This means that 'long double' instructions
|
||||
operate correctly, but 'double' computations often produce slightly
|
||||
different results as on strictly IEEE 754 conforming systems.
|
||||
|
||||
On some platforms, such as NetBSD, the default precision is set to
|
||||
"double precision". This means that 'long double' instructions will operate
|
||||
only as 'double', i.e. lead to wrong results. Similarly on FreeBSD 6.4, at
|
||||
least for the division of 'long double' numbers.
|
||||
|
||||
The FPU control word is under control of the application, i.e. it is
|
||||
not required to be set either way by the ABI. (In fact, the i386 ABI
|
||||
https://www.linux-mips.org/pub/linux/mips/doc/ABI/abi386-4.pdf page 3-12 = page 38
|
||||
is not clear about it. But in any case, gcc treats the control word
|
||||
like a "preserved" register: it emits code that assumes that the control
|
||||
word is preserved across calls, and it restores the control word at the
|
||||
end of functions that modify it.)
|
||||
|
||||
See Vincent Lefèvre's page https://www.vinc17.net/research/extended.en.html
|
||||
for a good explanation.
|
||||
See https://web.archive.org/web/20060905133417/http://www.uwsg.iu.edu/hypermail/linux/kernel/0103.0/0453.html
|
||||
some argumentation which setting should be the default. */
|
||||
|
||||
/* This header file provides the following facilities:
|
||||
fpucw_t integral type holding the value of 'fctrl'
|
||||
FPU_PC_MASK bit mask denoting the precision control
|
||||
FPU_PC_DOUBLE precision control for 53 bits mantissa
|
||||
FPU_PC_EXTENDED precision control for 64 bits mantissa
|
||||
GET_FPUCW () yields the current FPU control word
|
||||
SET_FPUCW (word) sets the FPU control word
|
||||
DECL_LONG_DOUBLE_ROUNDING variable declaration for
|
||||
BEGIN/END_LONG_DOUBLE_ROUNDING
|
||||
BEGIN_LONG_DOUBLE_ROUNDING () starts a sequence of instructions with
|
||||
'long double' safe operation precision
|
||||
END_LONG_DOUBLE_ROUNDING () ends a sequence of instructions with
|
||||
'long double' safe operation precision
|
||||
*/
|
||||
|
||||
/* Inline assembler like this works only with GNU C and clang. */
|
||||
#if (defined __i386__ || defined __x86_64__) && (defined __GNUC__ || defined __clang__)
|
||||
|
||||
typedef unsigned short fpucw_t; /* glibc calls this fpu_control_t */
|
||||
|
||||
# define FPU_PC_MASK 0x0300
|
||||
# define FPU_PC_DOUBLE 0x200 /* glibc calls this _FPU_DOUBLE */
|
||||
# define FPU_PC_EXTENDED 0x300 /* glibc calls this _FPU_EXTENDED */
|
||||
|
||||
# define GET_FPUCW() __extension__ \
|
||||
({ fpucw_t _cw; \
|
||||
__asm__ __volatile__ ("fnstcw %0" : "=m" (*&_cw)); \
|
||||
_cw; \
|
||||
})
|
||||
# define SET_FPUCW(word) __extension__ \
|
||||
(void)({ fpucw_t _ncw = (word); \
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (*&_ncw)); \
|
||||
})
|
||||
|
||||
# define DECL_LONG_DOUBLE_ROUNDING \
|
||||
fpucw_t oldcw;
|
||||
# define BEGIN_LONG_DOUBLE_ROUNDING() \
|
||||
(void)(oldcw = GET_FPUCW (), \
|
||||
SET_FPUCW ((oldcw & ~FPU_PC_MASK) | FPU_PC_EXTENDED))
|
||||
# define END_LONG_DOUBLE_ROUNDING() \
|
||||
SET_FPUCW (oldcw)
|
||||
|
||||
#else
|
||||
|
||||
typedef unsigned int fpucw_t;
|
||||
|
||||
# define FPU_PC_MASK 0
|
||||
# define FPU_PC_DOUBLE 0
|
||||
# define FPU_PC_EXTENDED 0
|
||||
|
||||
# define GET_FPUCW() 0
|
||||
# define SET_FPUCW(word) (void)(word)
|
||||
|
||||
# define DECL_LONG_DOUBLE_ROUNDING
|
||||
# define BEGIN_LONG_DOUBLE_ROUNDING()
|
||||
# define END_LONG_DOUBLE_ROUNDING()
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _FPUCW_H */
|
|
@ -1,53 +0,0 @@
|
|||
/* Make free() preserve errno.
|
||||
|
||||
Copyright (C) 2003, 2006, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Paul Eggert */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* A function definition is only needed if HAVE_FREE_POSIX is not defined. */
|
||||
#if !HAVE_FREE_POSIX
|
||||
|
||||
# include <errno.h>
|
||||
|
||||
void
|
||||
rpl_free (void *p)
|
||||
# undef free
|
||||
{
|
||||
# if defined __GNUC__ && !defined __clang__
|
||||
/* An invalid GCC optimization
|
||||
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98396>
|
||||
would optimize away the assignments in the code below, when link-time
|
||||
optimization (LTO) is enabled. Make the code more complicated, so that
|
||||
GCC does not grok how to optimize it. */
|
||||
int err[2];
|
||||
err[0] = errno;
|
||||
err[1] = errno;
|
||||
errno = 0;
|
||||
free (p);
|
||||
errno = err[errno == 0];
|
||||
# else
|
||||
int err = errno;
|
||||
free (p);
|
||||
errno = err;
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,168 +0,0 @@
|
|||
/* Split a double into fraction and mantissa.
|
||||
Copyright (C) 2007-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paolo Bonzini <bonzini@gnu.org>, 2003, and
|
||||
Bruno Haible <bruno@clisp.org>, 2007. */
|
||||
|
||||
#if ! defined USE_LONG_DOUBLE
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include <math.h>
|
||||
|
||||
#include <float.h>
|
||||
#ifdef USE_LONG_DOUBLE
|
||||
# include "isnanl-nolibm.h"
|
||||
# include "fpucw.h"
|
||||
#else
|
||||
# include "isnand-nolibm.h"
|
||||
#endif
|
||||
|
||||
/* This file assumes FLT_RADIX = 2. If FLT_RADIX is a power of 2 greater
|
||||
than 2, or not even a power of 2, some rounding errors can occur, so that
|
||||
then the returned mantissa is only guaranteed to be <= 1.0, not < 1.0. */
|
||||
|
||||
#ifdef USE_LONG_DOUBLE
|
||||
# define FUNC frexpl
|
||||
# define DOUBLE long double
|
||||
# define ISNAN isnanl
|
||||
# define DECL_ROUNDING DECL_LONG_DOUBLE_ROUNDING
|
||||
# define BEGIN_ROUNDING() BEGIN_LONG_DOUBLE_ROUNDING ()
|
||||
# define END_ROUNDING() END_LONG_DOUBLE_ROUNDING ()
|
||||
# define L_(literal) literal##L
|
||||
#else
|
||||
# define FUNC frexp
|
||||
# define DOUBLE double
|
||||
# define ISNAN isnand
|
||||
# define DECL_ROUNDING
|
||||
# define BEGIN_ROUNDING()
|
||||
# define END_ROUNDING()
|
||||
# define L_(literal) literal
|
||||
#endif
|
||||
|
||||
DOUBLE
|
||||
FUNC (DOUBLE x, int *expptr)
|
||||
{
|
||||
int sign;
|
||||
int exponent;
|
||||
DECL_ROUNDING
|
||||
|
||||
/* Test for NaN, infinity, and zero. */
|
||||
if (ISNAN (x) || x + x == x)
|
||||
{
|
||||
*expptr = 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
sign = 0;
|
||||
if (x < 0)
|
||||
{
|
||||
x = - x;
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
BEGIN_ROUNDING ();
|
||||
|
||||
{
|
||||
/* Since the exponent is an 'int', it fits in 64 bits. Therefore the
|
||||
loops are executed no more than 64 times. */
|
||||
DOUBLE pow2[64]; /* pow2[i] = 2^2^i */
|
||||
DOUBLE powh[64]; /* powh[i] = 2^-2^i */
|
||||
int i;
|
||||
|
||||
exponent = 0;
|
||||
if (x >= L_(1.0))
|
||||
{
|
||||
/* A positive exponent. */
|
||||
DOUBLE pow2_i; /* = pow2[i] */
|
||||
DOUBLE powh_i; /* = powh[i] */
|
||||
|
||||
/* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i,
|
||||
x * 2^exponent = argument, x >= 1.0. */
|
||||
for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5);
|
||||
;
|
||||
i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i)
|
||||
{
|
||||
if (x >= pow2_i)
|
||||
{
|
||||
exponent += (1 << i);
|
||||
x *= powh_i;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
pow2[i] = pow2_i;
|
||||
powh[i] = powh_i;
|
||||
}
|
||||
/* Avoid making x too small, as it could become a denormalized
|
||||
number and thus lose precision. */
|
||||
while (i > 0 && x < pow2[i - 1])
|
||||
{
|
||||
i--;
|
||||
powh_i = powh[i];
|
||||
}
|
||||
exponent += (1 << i);
|
||||
x *= powh_i;
|
||||
/* Here 2^-2^i <= x < 1.0. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A negative or zero exponent. */
|
||||
DOUBLE pow2_i; /* = pow2[i] */
|
||||
DOUBLE powh_i; /* = powh[i] */
|
||||
|
||||
/* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i,
|
||||
x * 2^exponent = argument, x < 1.0. */
|
||||
for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5);
|
||||
;
|
||||
i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i)
|
||||
{
|
||||
if (x < powh_i)
|
||||
{
|
||||
exponent -= (1 << i);
|
||||
x *= pow2_i;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
pow2[i] = pow2_i;
|
||||
powh[i] = powh_i;
|
||||
}
|
||||
/* Here 2^-2^i <= x < 1.0. */
|
||||
}
|
||||
|
||||
/* Invariants: x * 2^exponent = argument, and 2^-2^i <= x < 1.0. */
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
if (x < powh[i])
|
||||
{
|
||||
exponent -= (1 << i);
|
||||
x *= pow2[i];
|
||||
}
|
||||
}
|
||||
/* Here 0.5 <= x < 1.0. */
|
||||
}
|
||||
|
||||
if (sign < 0)
|
||||
x = - x;
|
||||
|
||||
END_ROUNDING ();
|
||||
|
||||
*expptr = exponent;
|
||||
return x;
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/* Split a 'long double' into fraction and mantissa.
|
||||
Copyright (C) 2007, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
|
||||
|
||||
/* Specification. */
|
||||
# include <math.h>
|
||||
|
||||
long double
|
||||
frexpl (long double x, int *expptr)
|
||||
{
|
||||
return frexp (x, expptr);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# define USE_LONG_DOUBLE
|
||||
# include "frexp.c"
|
||||
|
||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||
/* Set the error indicator of a stream.
|
||||
Copyright (C) 2007-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "fseterr.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "stdio-impl.h"
|
||||
|
||||
/* This file is not used on systems that have the __fseterr function,
|
||||
namely musl libc. */
|
||||
|
||||
void
|
||||
fseterr (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_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
|
||||
/* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
fp->_flags |= _IO_ERR_SEEN;
|
||||
#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
|
||||
/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
|
||||
fp_->_flags |= __SERR;
|
||||
#elif defined __EMX__ /* emx+gcc */
|
||||
fp->_flags |= _IOERR;
|
||||
#elif defined __minix /* Minix */
|
||||
fp->_flags |= _IOERR;
|
||||
#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */
|
||||
fp_->_flag |= _IOERR;
|
||||
#elif defined __UCLIBC__ /* uClibc */
|
||||
fp->__modeflags |= __FLAG_ERROR;
|
||||
#elif defined __QNX__ /* QNX */
|
||||
fp->_Mode |= 0x200 /* _MERR */;
|
||||
#elif defined __MINT__ /* Atari FreeMiNT */
|
||||
fp->__error = 1;
|
||||
#elif defined EPLAN9 /* Plan9 */
|
||||
if (fp->state != 0 /* CLOSED */)
|
||||
fp->state = 5 /* ERR */;
|
||||
#elif 0 /* unknown */
|
||||
/* Portable fallback, based on an idea by Rich Felker.
|
||||
Wow! 6 system calls for something that is just a bit operation!
|
||||
Not activated on any system, because there is no way to repair FP when
|
||||
the sequence of system calls fails, and library code should not call
|
||||
abort(). */
|
||||
int saved_errno;
|
||||
int fd;
|
||||
int fd2;
|
||||
|
||||
saved_errno = errno;
|
||||
fflush (fp);
|
||||
fd = fileno (fp);
|
||||
fd2 = dup (fd);
|
||||
if (fd2 >= 0)
|
||||
{
|
||||
close (fd);
|
||||
fputc ('\0', fp); /* This should set the error indicator. */
|
||||
fflush (fp); /* Or this. */
|
||||
if (dup2 (fd2, fd) < 0)
|
||||
/* Whee... we botched the stream and now cannot restore it! */
|
||||
abort ();
|
||||
close (fd2);
|
||||
}
|
||||
errno = saved_errno;
|
||||
#else
|
||||
#error "Please port gnulib fseterr.c to your platform! Look at the definitions of ferror and clearerr on your system, then report this to bug-gnulib."
|
||||
#endif
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/* Set the error indicator of a stream.
|
||||
Copyright (C) 2007, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _FSETERR_H
|
||||
#define _FSETERR_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Set the error indicator of the stream FP.
|
||||
The "error indicator" is set when an I/O operation on the stream fails, and
|
||||
is cleared (together with the "end-of-file" indicator) by clearerr (FP). */
|
||||
|
||||
#if HAVE___FSETERR /* musl libc */
|
||||
|
||||
# include <stdio_ext.h>
|
||||
# define fseterr(fp) __fseterr (fp)
|
||||
|
||||
#else
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
extern void fseterr (FILE *fp);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _FSETERR_H */
|
|
@ -1,148 +0,0 @@
|
|||
/* Work around an fstatat bug on Solaris 9.
|
||||
|
||||
Copyright (C) 2006, 2009-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert and Jim Meyering. */
|
||||
|
||||
/* If the user's config.h happens to include <sys/stat.h>, let it include only
|
||||
the system's <sys/stat.h> here, so that orig_fstatat doesn't recurse to
|
||||
rpl_fstatat. */
|
||||
#define __need_system_sys_stat_h
|
||||
#include <config.h>
|
||||
|
||||
/* Get the original definition of fstatat. It might be defined as a macro. */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#undef __need_system_sys_stat_h
|
||||
|
||||
#if HAVE_FSTATAT && HAVE_WORKING_FSTATAT_ZERO_FLAG
|
||||
static int
|
||||
orig_fstatat (int fd, char const *filename, struct stat *buf, int flags)
|
||||
{
|
||||
return fstatat (fd, filename, buf, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __osf__
|
||||
/* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc
|
||||
eliminates this include because of the preliminary #include <sys/stat.h>
|
||||
above. */
|
||||
# include "sys/stat.h"
|
||||
#else
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include "stat-time.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if HAVE_FSTATAT && HAVE_WORKING_FSTATAT_ZERO_FLAG
|
||||
|
||||
# ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||
# define LSTAT_FOLLOWS_SLASHED_SYMLINK 0
|
||||
# endif
|
||||
|
||||
static int
|
||||
normal_fstatat (int fd, char const *file, struct stat *st, int flag)
|
||||
{
|
||||
return stat_time_normalize (orig_fstatat (fd, file, st, flag), st);
|
||||
}
|
||||
|
||||
/* fstatat should always follow symbolic links that end in /, but on
|
||||
Solaris 9 it doesn't if AT_SYMLINK_NOFOLLOW is specified.
|
||||
Likewise, trailing slash on a non-directory should be an error.
|
||||
These are the same problems that lstat.c and stat.c address, so
|
||||
solve it in a similar way.
|
||||
|
||||
AIX 7.1 fstatat (AT_FDCWD, ..., 0) always fails, which is a bug.
|
||||
Work around this bug if FSTATAT_AT_FDCWD_0_BROKEN is nonzero. */
|
||||
|
||||
int
|
||||
rpl_fstatat (int fd, char const *file, struct stat *st, int flag)
|
||||
{
|
||||
int result = normal_fstatat (fd, file, st, flag);
|
||||
size_t len;
|
||||
|
||||
if (LSTAT_FOLLOWS_SLASHED_SYMLINK || result != 0)
|
||||
return result;
|
||||
len = strlen (file);
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
/* Fix lstat behavior. */
|
||||
if (file[len - 1] != '/' || S_ISDIR (st->st_mode))
|
||||
return 0;
|
||||
if (!S_ISLNK (st->st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
result = normal_fstatat (fd, file, st, flag & ~AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
/* Fix stat behavior. */
|
||||
if (result == 0 && !S_ISDIR (st->st_mode) && file[len - 1] == '/')
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#else /* ! (HAVE_FSTATAT && HAVE_WORKING_FSTATAT_ZERO_FLAG) */
|
||||
|
||||
/* On mingw, the gnulib <sys/stat.h> defines 'stat' as a function-like
|
||||
macro; but using it in AT_FUNC_F2 causes compilation failure
|
||||
because the preprocessor sees a use of a macro that requires two
|
||||
arguments but is only given one. Hence, we need an inline
|
||||
forwarder to get past the preprocessor. */
|
||||
static int
|
||||
stat_func (char const *name, struct stat *st)
|
||||
{
|
||||
return stat (name, st);
|
||||
}
|
||||
|
||||
/* Likewise, if there is no native 'lstat', then the gnulib
|
||||
<sys/stat.h> defined it as stat, which also needs adjustment. */
|
||||
# if !HAVE_LSTAT
|
||||
# undef lstat
|
||||
# define lstat stat_func
|
||||
# endif
|
||||
|
||||
/* Replacement for Solaris' function by the same name.
|
||||
<https://www.google.com/search?q=fstatat+site:docs.oracle.com>
|
||||
First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE").
|
||||
Failing that, simulate it via save_cwd/fchdir/(stat|lstat)/restore_cwd.
|
||||
If either the save_cwd or the restore_cwd fails (relatively unlikely),
|
||||
then give a diagnostic and exit nonzero.
|
||||
Otherwise, this function works just like Solaris' fstatat. */
|
||||
|
||||
# define AT_FUNC_NAME fstatat
|
||||
# define AT_FUNC_F1 lstat
|
||||
# define AT_FUNC_F2 stat_func
|
||||
# define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW
|
||||
# define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag
|
||||
# define AT_FUNC_POST_FILE_ARGS , st
|
||||
# include "at-func.c"
|
||||
# undef AT_FUNC_NAME
|
||||
# undef AT_FUNC_F1
|
||||
# undef AT_FUNC_F2
|
||||
# undef AT_FUNC_USE_F1_COND
|
||||
# undef AT_FUNC_POST_FILE_PARAM_DECLS
|
||||
# undef AT_FUNC_POST_FILE_ARGS
|
||||
|
||||
#endif /* !HAVE_FSTATAT */
|
|
@ -1,233 +0,0 @@
|
|||
/* fsusage.c -- return space usage of mounted file systems
|
||||
|
||||
Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2023 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "fsusage.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if STAT_STATVFS || STAT_STATVFS64 /* POSIX 1003.1-2001 (and later) with XSI */
|
||||
# include <sys/statvfs.h>
|
||||
#else
|
||||
/* Don't include backward-compatibility files unless they're needed.
|
||||
Eventually we'd like to remove all this cruft. */
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/stat.h>
|
||||
#if HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
#if HAVE_SYS_MOUNT_H
|
||||
# include <sys/mount.h>
|
||||
#endif
|
||||
#if HAVE_SYS_VFS_H
|
||||
# include <sys/vfs.h>
|
||||
#endif
|
||||
# if HAVE_SYS_FS_S5PARAM_H /* Fujitsu UXP/V */
|
||||
# include <sys/fs/s5param.h>
|
||||
# endif
|
||||
# if HAVE_SYS_STATFS_H
|
||||
# include <sys/statfs.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Many space usage primitives use all 1 bits to denote a value that is
|
||||
not applicable or unknown. Propagate this information by returning
|
||||
a uintmax_t value that is all 1 bits if X is all 1 bits, even if X
|
||||
is unsigned and narrower than uintmax_t. */
|
||||
#define PROPAGATE_ALL_ONES(x) \
|
||||
((sizeof (x) < sizeof (uintmax_t) \
|
||||
&& (~ (x) == (sizeof (x) < sizeof (int) \
|
||||
? - (1 << (sizeof (x) * CHAR_BIT)) \
|
||||
: 0))) \
|
||||
? UINTMAX_MAX : (uintmax_t) (x))
|
||||
|
||||
/* Extract the top bit of X as an uintmax_t value. */
|
||||
#define EXTRACT_TOP_BIT(x) ((x) \
|
||||
& ((uintmax_t) 1 << (sizeof (x) * CHAR_BIT - 1)))
|
||||
|
||||
/* If a value is negative, many space usage primitives store it into an
|
||||
integer variable by assignment, even if the variable's type is unsigned.
|
||||
So, if a space usage variable X's top bit is set, convert X to the
|
||||
uintmax_t value V such that (- (uintmax_t) V) is the negative of
|
||||
the original value. If X's top bit is clear, just yield X.
|
||||
Use PROPAGATE_TOP_BIT if the original value might be negative;
|
||||
otherwise, use PROPAGATE_ALL_ONES. */
|
||||
#define PROPAGATE_TOP_BIT(x) ((x) | ~ (EXTRACT_TOP_BIT (x) - 1))
|
||||
|
||||
#ifdef STAT_STATVFS
|
||||
/* Return true if statvfs works. This is false for statvfs on systems
|
||||
with GNU libc on Linux kernels before 2.6.36, which stats all
|
||||
preceding entries in /proc/mounts; that makes df hang if even one
|
||||
of the corresponding file systems is hard-mounted but not available. */
|
||||
# if ! (__linux__ && (__GLIBC__ || __UCLIBC__))
|
||||
/* The FRSIZE fallback is not required in this case. */
|
||||
# undef STAT_STATFS2_FRSIZE
|
||||
static int statvfs_works (void) { return 1; }
|
||||
# else
|
||||
# include <string.h> /* for strverscmp */
|
||||
# include <sys/utsname.h>
|
||||
# include <sys/statfs.h>
|
||||
# define STAT_STATFS2_BSIZE 1
|
||||
|
||||
static int
|
||||
statvfs_works (void)
|
||||
{
|
||||
static int statvfs_works_cache = -1;
|
||||
struct utsname name;
|
||||
if (statvfs_works_cache < 0)
|
||||
statvfs_works_cache = (uname (&name) == 0
|
||||
&& 0 <= strverscmp (name.release, "2.6.36"));
|
||||
return statvfs_works_cache;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Fill in the fields of FSP with information about space usage for
|
||||
the file system on which FILE resides.
|
||||
DISK is the device on which FILE is mounted, for space-getting
|
||||
methods that need to know it.
|
||||
Return 0 if successful, -1 if not. When returning -1, ensure that
|
||||
ERRNO is either a system error value, or zero if DISK is NULL
|
||||
on a system that requires a non-NULL value. */
|
||||
int
|
||||
get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
|
||||
{
|
||||
#ifdef STAT_STATVFS /* POSIX, except pre-2.6.36 glibc/Linux */
|
||||
|
||||
if (statvfs_works ())
|
||||
{
|
||||
struct statvfs vfsd;
|
||||
|
||||
if (statvfs (file, &vfsd) < 0)
|
||||
return -1;
|
||||
|
||||
/* f_frsize isn't guaranteed to be supported. */
|
||||
fsp->fsu_blocksize = (vfsd.f_frsize
|
||||
? PROPAGATE_ALL_ONES (vfsd.f_frsize)
|
||||
: PROPAGATE_ALL_ONES (vfsd.f_bsize));
|
||||
|
||||
fsp->fsu_blocks = PROPAGATE_ALL_ONES (vfsd.f_blocks);
|
||||
fsp->fsu_bfree = PROPAGATE_ALL_ONES (vfsd.f_bfree);
|
||||
fsp->fsu_bavail = PROPAGATE_TOP_BIT (vfsd.f_bavail);
|
||||
fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (vfsd.f_bavail) != 0;
|
||||
fsp->fsu_files = PROPAGATE_ALL_ONES (vfsd.f_files);
|
||||
fsp->fsu_ffree = PROPAGATE_ALL_ONES (vfsd.f_ffree);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined STAT_STATVFS64 /* AIX */
|
||||
|
||||
struct statvfs64 fsd;
|
||||
|
||||
if (statvfs64 (file, &fsd) < 0)
|
||||
return -1;
|
||||
|
||||
/* f_frsize isn't guaranteed to be supported. */
|
||||
fsp->fsu_blocksize = (fsd.f_frsize
|
||||
? PROPAGATE_ALL_ONES (fsd.f_frsize)
|
||||
: PROPAGATE_ALL_ONES (fsd.f_bsize));
|
||||
|
||||
#elif defined STAT_STATFS3_OSF1 /* OSF/1 */
|
||||
|
||||
struct statfs fsd;
|
||||
|
||||
if (statfs (file, &fsd, sizeof (struct statfs)) != 0)
|
||||
return -1;
|
||||
|
||||
fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);
|
||||
|
||||
#elif defined STAT_STATFS2_FRSIZE /* 2.6 < glibc/Linux < 2.6.36 */
|
||||
|
||||
struct statfs fsd;
|
||||
|
||||
if (statfs (file, &fsd) < 0)
|
||||
return -1;
|
||||
|
||||
fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_frsize);
|
||||
|
||||
#elif defined STAT_STATFS2_BSIZE /* glibc/Linux < 2.6, 4.3BSD, SunOS 4, \
|
||||
Mac OS X < 10.4, FreeBSD < 5.0, \
|
||||
NetBSD < 3.0, OpenBSD < 4.4 */
|
||||
|
||||
struct statfs fsd;
|
||||
|
||||
if (statfs (file, &fsd) < 0)
|
||||
return -1;
|
||||
|
||||
fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);
|
||||
|
||||
# ifdef STATFS_TRUNCATES_BLOCK_COUNTS
|
||||
|
||||
/* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
|
||||
struct statfs are truncated to 2GB. These conditions detect that
|
||||
truncation, presumably without botching the 4.1.1 case, in which
|
||||
the values are not truncated. The correct counts are stored in
|
||||
undocumented spare fields. */
|
||||
if (fsd.f_blocks == 0x7fffffff / fsd.f_bsize && fsd.f_spare[0] > 0)
|
||||
{
|
||||
fsd.f_blocks = fsd.f_spare[0];
|
||||
fsd.f_bfree = fsd.f_spare[1];
|
||||
fsd.f_bavail = fsd.f_spare[2];
|
||||
}
|
||||
# endif /* STATFS_TRUNCATES_BLOCK_COUNTS */
|
||||
|
||||
#elif defined STAT_STATFS2_FSIZE /* 4.4BSD and older NetBSD */
|
||||
|
||||
struct statfs fsd;
|
||||
|
||||
if (statfs (file, &fsd) < 0)
|
||||
return -1;
|
||||
|
||||
fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);
|
||||
|
||||
#elif defined STAT_STATFS4 /* SVR3, old Irix */
|
||||
|
||||
struct statfs fsd;
|
||||
|
||||
if (statfs (file, &fsd, sizeof fsd, 0) < 0)
|
||||
return -1;
|
||||
|
||||
/* Empirically, the block counts on most SVR3 and SVR3-derived
|
||||
systems seem to always be in terms of 512-byte blocks,
|
||||
no matter what value f_bsize has. */
|
||||
fsp->fsu_blocksize = 512;
|
||||
|
||||
#endif
|
||||
|
||||
#if (defined STAT_STATVFS64 || defined STAT_STATFS3_OSF1 \
|
||||
|| defined STAT_STATFS2_FRSIZE || defined STAT_STATFS2_BSIZE \
|
||||
|| defined STAT_STATFS2_FSIZE || defined STAT_STATFS4)
|
||||
|
||||
fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks);
|
||||
fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.f_bfree);
|
||||
fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.f_bavail);
|
||||
fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.f_bavail) != 0;
|
||||
fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.f_files);
|
||||
fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.f_ffree);
|
||||
|
||||
#endif
|
||||
|
||||
(void) disk; /* avoid argument-unused warning */
|
||||
return 0;
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/* fsusage.h -- declarations for file system space usage info
|
||||
|
||||
Copyright (C) 1991-1992, 1997, 2003-2006, 2009-2023 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Space usage statistics for a file system. Blocks are 512-byte. */
|
||||
|
||||
#if !defined FSUSAGE_H_
|
||||
# define FSUSAGE_H_
|
||||
|
||||
# include <stdint.h>
|
||||
|
||||
struct fs_usage
|
||||
{
|
||||
uintmax_t fsu_blocksize; /* Size of a block. */
|
||||
uintmax_t fsu_blocks; /* Total blocks. */
|
||||
uintmax_t fsu_bfree; /* Free blocks available to superuser. */
|
||||
uintmax_t fsu_bavail; /* Free blocks available to non-superuser. */
|
||||
bool fsu_bavail_top_bit_set; /* 1 if fsu_bavail represents a value < 0. */
|
||||
uintmax_t fsu_files; /* Total file nodes. */
|
||||
uintmax_t fsu_ffree; /* Free file nodes. */
|
||||
};
|
||||
|
||||
int get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp);
|
||||
|
||||
#endif
|
|
@ -1,87 +0,0 @@
|
|||
/* Emulate fsync on platforms that lack it, primarily Windows and
|
||||
cross-compilers like MinGW.
|
||||
|
||||
This is derived from sqlite3 sources.
|
||||
https://www.sqlite.org/src/finfo?name=src/os_win.c
|
||||
https://www.sqlite.org/copyright.html
|
||||
|
||||
Written by Richard W.M. Jones <rjones.at.redhat.com>
|
||||
|
||||
Copyright (C) 2008-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined _WIN32 && ! defined __CYGWIN__
|
||||
|
||||
/* FlushFileBuffers */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
|
||||
# include <errno.h>
|
||||
|
||||
/* Get _get_osfhandle. */
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# include <io.h>
|
||||
# endif
|
||||
|
||||
int
|
||||
fsync (int fd)
|
||||
{
|
||||
HANDLE h = (HANDLE) _get_osfhandle (fd);
|
||||
DWORD err;
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!FlushFileBuffers (h))
|
||||
{
|
||||
/* Translate some Windows errors into rough approximations of Unix
|
||||
* errors. MSDN is useless as usual - in this case it doesn't
|
||||
* document the full range of errors.
|
||||
*/
|
||||
err = GetLastError ();
|
||||
switch (err)
|
||||
{
|
||||
case ERROR_ACCESS_DENIED:
|
||||
/* For a read-only handle, fsync should succeed, even though we have
|
||||
no way to sync the access-time changes. */
|
||||
return 0;
|
||||
|
||||
/* eg. Trying to fsync a tty. */
|
||||
case ERROR_INVALID_HANDLE:
|
||||
errno = EINVAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EIO;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !Windows */
|
||||
|
||||
# error "This platform lacks fsync function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib."
|
||||
|
||||
#endif /* !Windows */
|
|
@ -1,151 +0,0 @@
|
|||
/* floating point to accurate string
|
||||
|
||||
Copyright (C) 2010-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert. */
|
||||
|
||||
/* This code can misbehave on some buggy or older platforms, when
|
||||
operating on arguments on floating types other than 'double', or
|
||||
when given unusual combinations of options. Gnulib's
|
||||
snprintf-posix module works around many of these problems.
|
||||
|
||||
This code relies on sprintf, strtod, etc. operating accurately;
|
||||
otherwise, the resulting strings could be inaccurate or too long. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "ftoastr.h"
|
||||
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef C_LOCALE
|
||||
# include "c-snprintf.h"
|
||||
# include "c-strtod.h"
|
||||
# define PREFIX(name) c_ ## name
|
||||
#else
|
||||
# define PREFIX(name) name
|
||||
#endif
|
||||
|
||||
#if LENGTH == 3
|
||||
# define FLOAT long double
|
||||
# define FLOAT_DIG LDBL_DIG
|
||||
# define FLOAT_MIN LDBL_MIN
|
||||
# define FLOAT_PREC_BOUND _GL_LDBL_PREC_BOUND
|
||||
# define FTOASTR PREFIX (ldtoastr)
|
||||
# define PROMOTED_FLOAT long double
|
||||
# define STRTOF PREFIX (strtold)
|
||||
#elif LENGTH == 2
|
||||
# define FLOAT double
|
||||
# define FLOAT_DIG DBL_DIG
|
||||
# define FLOAT_MIN DBL_MIN
|
||||
# define FLOAT_PREC_BOUND _GL_DBL_PREC_BOUND
|
||||
# define FTOASTR PREFIX (dtoastr)
|
||||
# define PROMOTED_FLOAT double
|
||||
#else
|
||||
# define LENGTH 1
|
||||
# define FLOAT float
|
||||
# define FLOAT_DIG FLT_DIG
|
||||
# define FLOAT_MIN FLT_MIN
|
||||
# define FLOAT_PREC_BOUND _GL_FLT_PREC_BOUND
|
||||
# define FTOASTR PREFIX (ftoastr)
|
||||
# define PROMOTED_FLOAT double
|
||||
# if HAVE_STRTOF
|
||||
# define STRTOF strtof
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* On pre-C99 hosts, approximate strtof with strtod. This
|
||||
may generate one or two extra digits, but that's better than not
|
||||
working at all. */
|
||||
#ifndef STRTOF
|
||||
# define STRTOF PREFIX (strtod)
|
||||
#endif
|
||||
|
||||
/* On hosts where it's not known that snprintf works, use sprintf to
|
||||
implement the subset needed here. Typically BUFSIZE is big enough
|
||||
and there's little or no performance hit. */
|
||||
#ifdef C_LOCALE
|
||||
# undef snprintf
|
||||
# define snprintf c_snprintf
|
||||
#elif ! GNULIB_SNPRINTF
|
||||
# undef snprintf
|
||||
# define snprintf ftoastr_snprintf
|
||||
static int
|
||||
ftoastr_snprintf (char *buf, size_t bufsize, char const *format,
|
||||
int width, int prec, FLOAT x)
|
||||
{
|
||||
PROMOTED_FLOAT promoted_x = x;
|
||||
char width_0_buffer[LENGTH == 1 ? FLT_BUFSIZE_BOUND
|
||||
: LENGTH == 2 ? DBL_BUFSIZE_BOUND
|
||||
: LDBL_BUFSIZE_BOUND];
|
||||
int n = width;
|
||||
if (bufsize < sizeof width_0_buffer)
|
||||
{
|
||||
n = sprintf (width_0_buffer, format, 0, prec, promoted_x);
|
||||
if (n < 0)
|
||||
return n;
|
||||
if (n < width)
|
||||
n = width;
|
||||
}
|
||||
if (n < bufsize)
|
||||
n = sprintf (buf, format, width, prec, promoted_x);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
FTOASTR (char *buf, size_t bufsize, int flags, int width, FLOAT x)
|
||||
{
|
||||
/* The following method is simple but slow.
|
||||
For ideas about speeding things up, please see:
|
||||
|
||||
Andrysco M, Jhala R, Lerner S. Printing floating-point numbers:
|
||||
a faster, always correct method. ACM SIGPLAN notices - POPL '16.
|
||||
2016;51(1):555-67 <https://doi.org/10.1145/2914770.2837654>; draft at
|
||||
<https://cseweb.ucsd.edu/~lerner/papers/fp-printing-popl16.pdf>. */
|
||||
|
||||
PROMOTED_FLOAT promoted_x = x;
|
||||
char format[sizeof "%-+ 0*.*Lg"];
|
||||
FLOAT abs_x = x < 0 ? -x : x;
|
||||
int prec;
|
||||
|
||||
char *p = format;
|
||||
*p++ = '%';
|
||||
|
||||
/* Support flags that generate output parsable by strtof. */
|
||||
*p = '-'; p += (flags & FTOASTR_LEFT_JUSTIFY ) != 0;
|
||||
*p = '+'; p += (flags & FTOASTR_ALWAYS_SIGNED ) != 0;
|
||||
*p = ' '; p += (flags & FTOASTR_SPACE_POSITIVE) != 0;
|
||||
*p = '0'; p += (flags & FTOASTR_ZERO_PAD ) != 0;
|
||||
|
||||
*p++ = '*';
|
||||
*p++ = '.';
|
||||
*p++ = '*';
|
||||
*p = 'L'; p += 2 < LENGTH;
|
||||
*p++ = flags & FTOASTR_UPPER_E ? 'G' : 'g';
|
||||
*p = '\0';
|
||||
|
||||
for (prec = abs_x < FLOAT_MIN ? 1 : FLOAT_DIG; ; prec++)
|
||||
{
|
||||
int n = snprintf (buf, bufsize, format, width, prec, promoted_x);
|
||||
if (n < 0
|
||||
|| FLOAT_PREC_BOUND <= prec
|
||||
|| (n < bufsize && STRTOF (buf, NULL) == x))
|
||||
return n;
|
||||
}
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
/* floating point to accurate string
|
||||
|
||||
Copyright (C) 2010-2023 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert. */
|
||||
|
||||
#ifndef _GL_FTOASTR_H
|
||||
#define _GL_FTOASTR_H
|
||||
|
||||
#include "intprops.h"
|
||||
#include <float.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Store into BUF (of size BUFSIZE) an accurate minimal-precision
|
||||
string representation of a floating point number. FLAGS affect the
|
||||
formatting of the number. Pad the output string with spaces as
|
||||
necessary to width WIDTH bytes, in the style of printf. WIDTH must
|
||||
be nonnegative. X is the floating-point number to be converted.
|
||||
|
||||
Return the number of bytes stored into BUF, not counting the
|
||||
terminating null. However, do not overrun BUF: if BUF is too
|
||||
small, return a fairly tight (but not necessarily exact) upper
|
||||
bound on the value that would have been returned if BUF had been
|
||||
big enough. If SIZE is zero, BUF may be a null pointer. On error
|
||||
(e.g., returned value would exceed INT_MAX), return -1 and set
|
||||
errno.
|
||||
|
||||
Example:
|
||||
|
||||
char buf[DBL_BUFSIZE_BOUND];
|
||||
int r = dtoastr (buf, sizeof buf, 0, 0, 0.1);
|
||||
|
||||
In the C locale, this sets R to 3 and stores "0.1" into BUF. */
|
||||
|
||||
int ftoastr (char *buf, size_t bufsize, int flags, int width, float x);
|
||||
int dtoastr (char *buf, size_t bufsize, int flags, int width, double x);
|
||||
int ldtoastr (char *buf, size_t bufsize, int flags, int width, long double x);
|
||||
|
||||
/* The last two functions except that the formatting takes place in
|
||||
the C locale. */
|
||||
int c_dtoastr (char *buf, size_t bufsize, int flags, int width, double x);
|
||||
int c_ldtoastr (char *buf, size_t bufsize, int flags, int width, long double x);
|
||||
|
||||
|
||||
/* Flag values for ftoastr etc. These can be ORed together. */
|
||||
enum
|
||||
{
|
||||
/* Left justify within the width; the default is right justification. */
|
||||
FTOASTR_LEFT_JUSTIFY = 1,
|
||||
|
||||
/* Output "+" before positive numbers; the default outputs nothing. */
|
||||
FTOASTR_ALWAYS_SIGNED = 2,
|
||||
|
||||
/* Output " " before positive numbers; ignored if
|
||||
FTOASTR_ALWAYS_SIGNED is also given. */
|
||||
FTOASTR_SPACE_POSITIVE = 4,
|
||||
|
||||
/* Pad with zeros instead of spaces; ignored if FTOASTR_LEFT_JUSTIFY
|
||||
is also given. */
|
||||
FTOASTR_ZERO_PAD = 8,
|
||||
|
||||
/* Use 'E' instead of 'e' before the exponent. */
|
||||
FTOASTR_UPPER_E = 16
|
||||
};
|
||||
|
||||
|
||||
/* _GL_FLT_PREC_BOUND is an upper bound on the precision needed to
|
||||
represent a float value without losing information. Likewise for
|
||||
_GL_DBL_PREC_BOUND and double, and _GL_LDBL_PREC_BOUND and long double.
|
||||
These are macros, not enums, to work around a bug in IBM xlc 12.1. */
|
||||
|
||||
#if FLT_RADIX == 10 /* decimal floating point */
|
||||
# define _GL_FLT_PREC_BOUND FLT_MANT_DIG
|
||||
# define _GL_DBL_PREC_BOUND DBL_MANT_DIG
|
||||
# define _GL_LDBL_PREC_BOUND LDBL_MANT_DIG
|
||||
#else
|
||||
|
||||
/* An upper bound on the number of bits needed to represent a single
|
||||
digit in a floating-point fraction. */
|
||||
# if FLT_RADIX == 2 /* IEEE 754 floating point, VAX floating point, etc. */
|
||||
# define _GL_FLOAT_DIG_BITS_BOUND 1
|
||||
# elif FLT_RADIX <= 16 /* IBM hex floating point has FLT_RADIX == 16. */
|
||||
# define _GL_FLOAT_DIG_BITS_BOUND 4
|
||||
# else /* no machine is this bad, but let's be complete */
|
||||
# define _GL_FLOAT_DIG_BITS_BOUND ((int) TYPE_WIDTH (int) - 1)
|
||||
# endif
|
||||
|
||||
/* An upper bound on the number of decimal digits needed to represent
|
||||
a floating point number accurately, assuming a fraction contains
|
||||
DIG digits. For why the "+ 1" is needed, see "Binary to Decimal
|
||||
Conversion" in David Goldberg's paper "What Every Computer
|
||||
Scientist Should Know About Floating-Point Arithmetic"
|
||||
<https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html>. */
|
||||
# define _GL_FLOAT_PREC_BOUND(dig) \
|
||||
(INT_BITS_STRLEN_BOUND ((dig) * _GL_FLOAT_DIG_BITS_BOUND) + 1)
|
||||
|
||||
# define _GL_FLT_PREC_BOUND _GL_FLOAT_PREC_BOUND ( FLT_MANT_DIG)
|
||||
# define _GL_DBL_PREC_BOUND _GL_FLOAT_PREC_BOUND ( DBL_MANT_DIG)
|
||||
# define _GL_LDBL_PREC_BOUND _GL_FLOAT_PREC_BOUND (LDBL_MANT_DIG)
|
||||
#endif
|
||||
|
||||
|
||||
/* Bound on the number of bytes printed for an exponent in the range
|
||||
MIN..MAX, where MIN < 0 < MAX; printf always prints a sign and at
|
||||
least 2 digits. Although the maximum known exponent is 4932 for
|
||||
IEEE 754 binary128, support tight bounds for exponents up to a
|
||||
million, just in case. */
|
||||
#define _GL_FLOAT_EXPONENT_STRLEN_BOUND(min, max) \
|
||||
( -100 < (min) && (max) < 100 ? 3 \
|
||||
: -1000 < (min) && (max) < 1000 ? 4 \
|
||||
: -10000 < (min) && (max) < 10000 ? 5 \
|
||||
: -100000 < (min) && (max) < 100000 ? 6 \
|
||||
: -1000000 < (min) && (max) < 1000000 ? 7 \
|
||||
: INT_STRLEN_BOUND (int) /* not a tight bound */)
|
||||
|
||||
/* A reasonably tight bound on the length of a type-T floating value
|
||||
formatted with ftoastr etc. Room is needed for sign, fraction
|
||||
digits, decimal point, "e", and exponent. POINTLEN should be a
|
||||
reasonably tight bound on the string length of the decimal
|
||||
point. */
|
||||
#define _GL_FLOAT_STRLEN_BOUND_L(t, pointlen) \
|
||||
(1 + _GL_##t##_PREC_BOUND + pointlen + 1 \
|
||||
+ _GL_FLOAT_EXPONENT_STRLEN_BOUND (t##_MIN_10_EXP, t##_MAX_10_EXP))
|
||||
#define FLT_STRLEN_BOUND_L(pointlen) _GL_FLOAT_STRLEN_BOUND_L ( FLT, pointlen)
|
||||
#define DBL_STRLEN_BOUND_L(pointlen) _GL_FLOAT_STRLEN_BOUND_L ( DBL, pointlen)
|
||||
#define LDBL_STRLEN_BOUND_L(pointlen) _GL_FLOAT_STRLEN_BOUND_L (LDBL, pointlen)
|
||||
|
||||
/* Looser bounds that are locale-independent and are integral constant
|
||||
expressions. */
|
||||
#define FLT_STRLEN_BOUND FLT_STRLEN_BOUND_L (MB_LEN_MAX)
|
||||
#define DBL_STRLEN_BOUND DBL_STRLEN_BOUND_L (MB_LEN_MAX)
|
||||
#define LDBL_STRLEN_BOUND LDBL_STRLEN_BOUND_L (MB_LEN_MAX)
|
||||
|
||||
/* Looser, locale-independent bounds that include the trailing null byte. */
|
||||
#define FLT_BUFSIZE_BOUND ( FLT_STRLEN_BOUND + 1)
|
||||
#define DBL_BUFSIZE_BOUND ( DBL_STRLEN_BOUND + 1)
|
||||
#define LDBL_BUFSIZE_BOUND (LDBL_STRLEN_BOUND + 1)
|
||||
|
||||
#endif /* _GL_FTOASTR_H */
|
|
@ -1,37 +0,0 @@
|
|||
/* Set the access and modification time of an open fd.
|
||||
Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Eric Blake */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "utimens.h"
|
||||
|
||||
/* Set the access and modification timestamps of FD to be
|
||||
TIMESPEC[0] and TIMESPEC[1], respectively.
|
||||
Fail with ENOSYS on systems without futimes (or equivalent).
|
||||
If TIMESPEC is null, set the timestamps to the current time.
|
||||
Return 0 on success, -1 (setting errno) on failure. */
|
||||
int
|
||||
futimens (int fd, struct timespec const times[2])
|
||||
{
|
||||
/* fdutimens also works around bugs in native futimens, when running
|
||||
with glibc compiled against newer headers but on a Linux kernel
|
||||
older than 2.6.32. */
|
||||
return fdutimens (fd, NULL, times);
|
||||
}
|
|
@ -1,291 +0,0 @@
|
|||
/* Get permissions of a file. -*- coding: utf-8 -*-
|
||||
|
||||
Copyright (C) 2002-2003, 2005-2023 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "acl.h"
|
||||
|
||||
#include "acl-internal.h"
|
||||
|
||||
/* Read the permissions of a file into CTX. If DESC is a valid file descriptor,
|
||||
use file descriptor operations, else use filename based operations on NAME.
|
||||
MODE is the file mode obtained from a previous stat call.
|
||||
Return 0 if successful. Return -1 and set errno upon failure. */
|
||||
|
||||
int
|
||||
get_permissions (const char *name, int desc, mode_t mode,
|
||||
struct permission_context *ctx)
|
||||
{
|
||||
memset (ctx, 0, sizeof *ctx);
|
||||
ctx->mode = mode;
|
||||
|
||||
#if USE_ACL && HAVE_ACL_GET_FILE
|
||||
/* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
|
||||
/* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
# if !HAVE_ACL_TYPE_EXTENDED
|
||||
/* Linux, FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
|
||||
if (HAVE_ACL_GET_FD && desc != -1)
|
||||
ctx->acl = acl_get_fd (desc);
|
||||
else
|
||||
ctx->acl = acl_get_file (name, ACL_TYPE_ACCESS);
|
||||
if (ctx->acl == NULL)
|
||||
return acl_errno_valid (errno) ? -1 : 0;
|
||||
|
||||
/* With POSIX ACLs, a file cannot have "no" acl; a file without
|
||||
extended permissions has a "minimal" acl which is equivalent to the
|
||||
file mode. */
|
||||
|
||||
if (S_ISDIR (mode))
|
||||
{
|
||||
ctx->default_acl = acl_get_file (name, ACL_TYPE_DEFAULT);
|
||||
if (ctx->default_acl == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
# if HAVE_ACL_TYPE_NFS4 /* FreeBSD */
|
||||
|
||||
/* TODO (see set_permissions). */
|
||||
|
||||
# endif
|
||||
|
||||
# else /* HAVE_ACL_TYPE_EXTENDED */
|
||||
/* Mac OS X */
|
||||
|
||||
/* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS)
|
||||
and acl_get_file (name, ACL_TYPE_DEFAULT)
|
||||
always return NULL / EINVAL. You have to use
|
||||
acl_get_file (name, ACL_TYPE_EXTENDED)
|
||||
or acl_get_fd (open (name, ...))
|
||||
to retrieve an ACL.
|
||||
On the other hand,
|
||||
acl_set_file (name, ACL_TYPE_ACCESS, acl)
|
||||
and acl_set_file (name, ACL_TYPE_DEFAULT, acl)
|
||||
have the same effect as
|
||||
acl_set_file (name, ACL_TYPE_EXTENDED, acl):
|
||||
Each of these calls sets the file's ACL. */
|
||||
|
||||
if (HAVE_ACL_GET_FD && desc != -1)
|
||||
ctx->acl = acl_get_fd (desc);
|
||||
else
|
||||
ctx->acl = acl_get_file (name, ACL_TYPE_EXTENDED);
|
||||
if (ctx->acl == NULL)
|
||||
return acl_errno_valid (errno) ? -1 : 0;
|
||||
|
||||
# endif
|
||||
|
||||
#elif USE_ACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
|
||||
|
||||
/* Solaris 2.5 through Solaris 10, Cygwin, and contemporaneous versions
|
||||
of Unixware. The acl() call returns the access and default ACL both
|
||||
at once. */
|
||||
# ifdef ACE_GETACL
|
||||
/* Solaris also has a different variant of ACLs, used in ZFS and NFSv4
|
||||
file systems (whereas the other ones are used in UFS file systems).
|
||||
There is an API
|
||||
pathconf (name, _PC_ACL_ENABLED)
|
||||
fpathconf (desc, _PC_ACL_ENABLED)
|
||||
that allows us to determine which of the two kinds of ACLs is supported
|
||||
for the given file. But some file systems may implement this call
|
||||
incorrectly, so better not use it.
|
||||
When fetching the source ACL, we simply fetch both ACL types.
|
||||
When setting the destination ACL, we try either ACL types, assuming
|
||||
that the kernel will translate the ACL from one form to the other.
|
||||
(See in <https://docs.oracle.com/cd/E86824_01/html/E54765/acl-2.html>
|
||||
the description of ENOTSUP.) */
|
||||
for (;;)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (desc != -1)
|
||||
ret = facl (desc, ACE_GETACLCNT, 0, NULL);
|
||||
else
|
||||
ret = acl (name, ACE_GETACLCNT, 0, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == ENOSYS || errno == EINVAL)
|
||||
ret = 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
ctx->ace_count = ret;
|
||||
|
||||
if (ctx->ace_count == 0)
|
||||
break;
|
||||
|
||||
ctx->ace_entries = (ace_t *) malloc (ctx->ace_count * sizeof (ace_t));
|
||||
if (ctx->ace_entries == NULL)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (desc != -1)
|
||||
ret = facl (desc, ACE_GETACL, ctx->ace_count, ctx->ace_entries);
|
||||
else
|
||||
ret = acl (name, ACE_GETACL, ctx->ace_count, ctx->ace_entries);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == ENOSYS || errno == EINVAL)
|
||||
{
|
||||
free (ctx->ace_entries);
|
||||
ctx->ace_entries = NULL;
|
||||
ctx->ace_count = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (ret <= ctx->ace_count)
|
||||
{
|
||||
ctx->ace_count = ret;
|
||||
break;
|
||||
}
|
||||
/* Huh? The number of ACL entries has increased since the last call.
|
||||
Repeat. */
|
||||
free (ctx->ace_entries);
|
||||
ctx->ace_entries = NULL;
|
||||
}
|
||||
# endif
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (desc != -1)
|
||||
ret = facl (desc, GETACLCNT, 0, NULL);
|
||||
else
|
||||
ret = acl (name, GETACLCNT, 0, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == ENOSYS || errno == ENOTSUP || errno == EOPNOTSUPP)
|
||||
ret = 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
ctx->count = ret;
|
||||
|
||||
if (ctx->count == 0)
|
||||
break;
|
||||
|
||||
ctx->entries = (aclent_t *) malloc (ctx->count * sizeof (aclent_t));
|
||||
if (ctx->entries == NULL)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (desc != -1)
|
||||
ret = facl (desc, GETACL, ctx->count, ctx->entries);
|
||||
else
|
||||
ret = acl (name, GETACL, ctx->count, ctx->entries);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == ENOSYS || errno == ENOTSUP || errno == EOPNOTSUPP)
|
||||
{
|
||||
free (ctx->entries);
|
||||
ctx->entries = NULL;
|
||||
ctx->count = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (ret <= ctx->count)
|
||||
{
|
||||
ctx->count = ret;
|
||||
break;
|
||||
}
|
||||
/* Huh? The number of ACL entries has increased since the last call.
|
||||
Repeat. */
|
||||
free (ctx->entries);
|
||||
ctx->entries = NULL;
|
||||
}
|
||||
|
||||
#elif USE_ACL && HAVE_GETACL /* HP-UX */
|
||||
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (desc != -1)
|
||||
ret = fgetacl (desc, NACLENTRIES, ctx->entries);
|
||||
else
|
||||
ret = getacl (name, NACLENTRIES, ctx->entries);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
|
||||
ret = 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else if (ret > NACLENTRIES)
|
||||
/* If NACLENTRIES cannot be trusted, use dynamic memory allocation. */
|
||||
abort ();
|
||||
ctx->count = ret;
|
||||
|
||||
# if HAVE_ACLV_H
|
||||
ret = acl ((char *) name, ACL_GET, NACLVENTRIES, ctx->aclv_entries);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
|
||||
ret = 0;
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
else if (ret > NACLVENTRIES)
|
||||
/* If NACLVENTRIES cannot be trusted, use dynamic memory allocation. */
|
||||
abort ();
|
||||
ctx->aclv_count = ret;
|
||||
# endif
|
||||
}
|
||||
|
||||
#elif USE_ACL && HAVE_ACLX_GET && ACL_AIX_WIP /* AIX */
|
||||
|
||||
/* TODO (see set_permissions). */
|
||||
|
||||
#elif USE_ACL && HAVE_STATACL /* older AIX */
|
||||
|
||||
{
|
||||
int ret;
|
||||
if (desc != -1)
|
||||
ret = fstatacl (desc, STX_NORMAL, &ctx->u.a, sizeof ctx->u);
|
||||
else
|
||||
ret = statacl ((char *) name, STX_NORMAL, &ctx->u.a, sizeof ctx->u);
|
||||
if (ret == 0)
|
||||
ctx->have_u = true;
|
||||
}
|
||||
|
||||
#elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */
|
||||
|
||||
{
|
||||
int ret = acl ((char *) name, ACL_GET, NACLENTRIES, ctx->entries);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
else if (ret > NACLENTRIES)
|
||||
/* If NACLENTRIES cannot be trusted, use dynamic memory allocation. */
|
||||
abort ();
|
||||
ctx->count = ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
/* getdelim.c --- Implementation of replacement getdelim function.
|
||||
Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2023 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Ported from glibc by Simon Josefsson. */
|
||||
|
||||
/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
|
||||
optimizes away the lineptr == NULL || n == NULL || fp == NULL tests below. */
|
||||
#define _GL_ARG_NONNULL(params)
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef SSIZE_MAX
|
||||
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
|
||||
#endif
|
||||
|
||||
#if USE_UNLOCKED_IO
|
||||
# include "unlocked-io.h"
|
||||
# define getc_maybe_unlocked(fp) getc(fp)
|
||||
#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED
|
||||
# undef flockfile
|
||||
# undef funlockfile
|
||||
# define flockfile(x) ((void) 0)
|
||||
# define funlockfile(x) ((void) 0)
|
||||
# define getc_maybe_unlocked(fp) getc(fp)
|
||||
#else
|
||||
# define getc_maybe_unlocked(fp) getc_unlocked(fp)
|
||||
#endif
|
||||
|
||||
static void
|
||||
alloc_failed (void)
|
||||
{
|
||||
#if defined _WIN32 && ! defined __CYGWIN__
|
||||
/* Avoid errno problem without using the realloc module; see:
|
||||
https://lists.gnu.org/r/bug-gnulib/2016-08/msg00025.html */
|
||||
errno = ENOMEM;
|
||||
#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)
|
||||
{
|
||||
char *new_lineptr;
|
||||
*n = 120;
|
||||
new_lineptr = (char *) realloc (*lineptr, *n);
|
||||
if (new_lineptr == NULL)
|
||||
{
|
||||
alloc_failed ();
|
||||
result = -1;
|
||||
goto unlock_return;
|
||||
}
|
||||
*lineptr = new_lineptr;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = getc_maybe_unlocked (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)
|
||||
{
|
||||
alloc_failed ();
|
||||
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,124 +0,0 @@
|
|||
/* getdtablesize() function: Return maximum possible file descriptor value + 1.
|
||||
Copyright (C) 2008-2023 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2008.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined _WIN32 && ! defined __CYGWIN__
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
# include "msvc-inval.h"
|
||||
# endif
|
||||
|
||||
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
static int
|
||||
_setmaxstdio_nothrow (int newmax)
|
||||
{
|
||||
int result;
|
||||
|
||||
TRY_MSVC_INVAL
|
||||
{
|
||||
result = _setmaxstdio (newmax);
|
||||
}
|
||||
CATCH_MSVC_INVAL
|
||||
{
|
||||
result = -1;
|
||||
}
|
||||
DONE_MSVC_INVAL;
|
||||
|
||||
return result;
|
||||
}
|
||||
# else
|
||||
# define _setmaxstdio_nothrow _setmaxstdio
|
||||
# endif
|
||||
|
||||
/* Cache for the previous getdtablesize () result. Safe to cache because
|
||||
Windows also lacks setrlimit. */
|
||||
static int dtablesize;
|
||||
|
||||
int
|
||||
getdtablesize (void)
|
||||
{
|
||||
if (dtablesize == 0)
|
||||
{
|
||||
/* We are looking for the number N such that the valid file descriptors
|
||||
are 0..N-1. It can be obtained through a loop as follows:
|
||||
{
|
||||
int fd;
|
||||
for (fd = 3; fd < 65536; fd++)
|
||||
if (dup2 (0, fd) == -1)
|
||||
break;
|
||||
return fd;
|
||||
}
|
||||
On Windows XP, the result is 2048.
|
||||
The drawback of this loop is that it allocates memory for a libc
|
||||
internal array that is never freed.
|
||||
|
||||
The number N can also be obtained as the upper bound for
|
||||
_getmaxstdio (). _getmaxstdio () returns the maximum number of open
|
||||
FILE objects. The sanity check in _setmaxstdio reveals the maximum
|
||||
number of file descriptors. This too allocates memory, but it is
|
||||
freed when we call _setmaxstdio with the original value. */
|
||||
int orig_max_stdio = _getmaxstdio ();
|
||||
unsigned int bound;
|
||||
for (bound = 0x10000; _setmaxstdio_nothrow (bound) < 0; bound = bound / 2)
|
||||
;
|
||||
_setmaxstdio_nothrow (orig_max_stdio);
|
||||
dtablesize = bound;
|
||||
}
|
||||
return dtablesize;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# include <limits.h>
|
||||
# include <sys/resource.h>
|
||||
|
||||
# ifndef RLIM_SAVED_CUR
|
||||
# define RLIM_SAVED_CUR RLIM_INFINITY
|
||||
# endif
|
||||
# ifndef RLIM_SAVED_MAX
|
||||
# define RLIM_SAVED_MAX RLIM_INFINITY
|
||||
# endif
|
||||
|
||||
# ifdef __CYGWIN__
|
||||
/* Cygwin 1.7.25 auto-increases the RLIMIT_NOFILE soft limit until it
|
||||
hits the compile-time constant hard limit of 3200. We might as
|
||||
well just report the hard limit. */
|
||||
# define rlim_cur rlim_max
|
||||
# endif
|
||||
|
||||
int
|
||||
getdtablesize (void)
|
||||
{
|
||||
struct rlimit lim;
|
||||
|
||||
if (getrlimit (RLIMIT_NOFILE, &lim) == 0
|
||||
&& 0 <= lim.rlim_cur && lim.rlim_cur <= INT_MAX
|
||||
&& lim.rlim_cur != RLIM_INFINITY
|
||||
&& lim.rlim_cur != RLIM_SAVED_CUR
|
||||
&& lim.rlim_cur != RLIM_SAVED_MAX)
|
||||
return lim.rlim_cur;
|
||||
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,125 +0,0 @@
|
|||
/* provide consistent interface to getgroups for systems that don't allow N==0
|
||||
|
||||
Copyright (C) 1996, 1999, 2003, 2006-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Jim Meyering */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if !HAVE_GETGROUPS
|
||||
|
||||
/* Provide a stub that fails with ENOSYS, since there is no group
|
||||
information available on mingw. */
|
||||
int
|
||||
getgroups (_GL_UNUSED int n, _GL_UNUSED GETGROUPS_T *groups)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else /* HAVE_GETGROUPS */
|
||||
|
||||
# undef getgroups
|
||||
# ifndef GETGROUPS_ZERO_BUG
|
||||
# define GETGROUPS_ZERO_BUG 0
|
||||
# endif
|
||||
|
||||
/* On OS X 10.6 and later, use the usual getgroups, not the one
|
||||
supplied when _DARWIN_C_SOURCE is defined. _DARWIN_C_SOURCE is
|
||||
normally defined, since it means "conform to POSIX, but add
|
||||
non-POSIX extensions even if that violates the POSIX namespace
|
||||
rules", which is what we normally want. But with getgroups there
|
||||
is an inconsistency, and _DARWIN_C_SOURCE means "change getgroups()
|
||||
so that it no longer works right". The BUGS section of compat(5)
|
||||
says that the behavior is dubious if you compile different sections
|
||||
of a program with different _DARWIN_C_SOURCE settings, so fix only
|
||||
the offending symbol. */
|
||||
# ifdef __APPLE__
|
||||
int posix_getgroups (int, gid_t []) __asm ("_getgroups");
|
||||
# define getgroups posix_getgroups
|
||||
# endif
|
||||
|
||||
/* On at least NeXTstep 3.2, getgroups (0, NULL) always fails.
|
||||
On other systems, it returns the number of supplemental
|
||||
groups for the process. This function handles that special case
|
||||
and lets the system-provided function handle all others. However,
|
||||
it can fail with ENOMEM if memory is tight. It is unspecified
|
||||
whether the effective group id is included in the list. */
|
||||
|
||||
int
|
||||
rpl_getgroups (int n, gid_t *group)
|
||||
{
|
||||
int n_groups;
|
||||
GETGROUPS_T *gbuf;
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n != 0 || !GETGROUPS_ZERO_BUG)
|
||||
{
|
||||
int result;
|
||||
if (sizeof *group == sizeof *gbuf)
|
||||
return getgroups (n, (GETGROUPS_T *) group);
|
||||
|
||||
if (SIZE_MAX / sizeof *gbuf <= n)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
gbuf = malloc (n * sizeof *gbuf);
|
||||
if (!gbuf)
|
||||
return -1;
|
||||
result = getgroups (n, gbuf);
|
||||
if (0 <= result)
|
||||
{
|
||||
n = result;
|
||||
while (n--)
|
||||
group[n] = gbuf[n];
|
||||
}
|
||||
free (gbuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
n = 20;
|
||||
while (1)
|
||||
{
|
||||
/* No need to worry about address arithmetic overflow here,
|
||||
since the ancient systems that we're running on have low
|
||||
limits on the number of secondary groups. */
|
||||
gbuf = malloc (n * sizeof *gbuf);
|
||||
if (!gbuf)
|
||||
return -1;
|
||||
n_groups = getgroups (n, gbuf);
|
||||
if (n_groups == -1 ? errno != EINVAL : n_groups < n)
|
||||
break;
|
||||
free (gbuf);
|
||||
n *= 2;
|
||||
}
|
||||
|
||||
free (gbuf);
|
||||
return n_groups;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GETGROUPS */
|
|
@ -1,27 +0,0 @@
|
|||
/* getline.c --- Implementation of replacement getline function.
|
||||
Copyright (C) 2005-2007, 2009-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* 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);
|
||||
}
|
|
@ -1,943 +0,0 @@
|
|||
/* Get the system load averages.
|
||||
|
||||
Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2023 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with gnulib.
|
||||
Bugs can be reported to bug-gnulib@gnu.org.
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Compile-time symbols that this file uses:
|
||||
|
||||
HAVE_PSTAT_GETDYNAMIC Define this if your system has the
|
||||
pstat_getdynamic function. I think it
|
||||
is unique to HPUX9. The best way to get the
|
||||
definition is through the AC_FUNC_GETLOADAVG
|
||||
macro that comes with autoconf 2.13 or newer.
|
||||
If that isn't an option, then just put
|
||||
AC_CHECK_FUNCS(pstat_getdynamic) in your
|
||||
configure.ac file.
|
||||
HAVE_LIBPERFSTAT Define this if your system has the
|
||||
perfstat_cpu_total function in libperfstat (AIX).
|
||||
FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist.
|
||||
KERNEL_FILE Name of the kernel file to nlist.
|
||||
LDAV_CVT() Scale the load average from the kernel.
|
||||
Returns a double.
|
||||
LDAV_SYMBOL Name of kernel symbol giving load average.
|
||||
LOAD_AVE_TYPE Type of the load average array in the kernel.
|
||||
Must be defined unless one of
|
||||
apollo, DGUX, NeXT, or UMAX is defined;
|
||||
or we have libkstat;
|
||||
otherwise, no load average is available.
|
||||
HAVE_NLIST_H nlist.h is available. NLIST_STRUCT defaults
|
||||
to this.
|
||||
NLIST_STRUCT Include nlist.h, not a.out.h.
|
||||
N_NAME_POINTER The nlist n_name element is a pointer,
|
||||
not an array.
|
||||
HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'.
|
||||
LINUX_LDAV_FILE [__linux__, __ANDROID__, __CYGWIN__]: File
|
||||
containing load averages.
|
||||
|
||||
Specific system predefines this file uses, aside from setting
|
||||
default values if not emacs:
|
||||
|
||||
apollo
|
||||
BSD Real BSD, not just BSD-like.
|
||||
DGUX
|
||||
eunice UNIX emulator under VMS.
|
||||
hpux
|
||||
__MSDOS__ No-op for MSDOS.
|
||||
NeXT
|
||||
sgi
|
||||
UMAX
|
||||
UMAX4_3
|
||||
VMS
|
||||
_WIN32 Native Windows (possibly also defined on Cygwin)
|
||||
__linux__, __ANDROID__ Linux: assumes /proc file system mounted.
|
||||
Support from Michael K. Johnson.
|
||||
__CYGWIN__ Cygwin emulates linux /proc/loadavg.
|
||||
__NetBSD__ NetBSD: assumes /kern file system mounted.
|
||||
|
||||
In addition, to avoid nesting many #ifdefs, we internally set
|
||||
LDAV_DONE to indicate that the load average has been computed.
|
||||
|
||||
We also #define LDAV_PRIVILEGED if a program will require
|
||||
special installation to be able to call getloadavg. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
# include <sys/types.h>
|
||||
|
||||
# if HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
|
||||
# include "intprops.h"
|
||||
|
||||
# if defined _WIN32 && ! defined __CYGWIN__ && ! defined WINDOWS32
|
||||
# define WINDOWS32
|
||||
# endif
|
||||
|
||||
# ifdef NeXT
|
||||
/* NeXT in the 2.{0,1,2} releases defines BSD in <sys/param.h>, which
|
||||
conflicts with the definition understood in this file, that this
|
||||
really is BSD. */
|
||||
# undef BSD
|
||||
|
||||
/* NeXT defines FSCALE in <sys/param.h>. However, we take FSCALE being
|
||||
defined to mean that the nlist method should be used, which is not true. */
|
||||
# undef FSCALE
|
||||
# endif
|
||||
|
||||
/* Same issues as for NeXT apply to the HURD-based GNU system. */
|
||||
# ifdef __GNU__
|
||||
# undef BSD
|
||||
# undef FSCALE
|
||||
# endif /* __GNU__ */
|
||||
|
||||
/* Set values that are different from the defaults, which are
|
||||
set a little farther down with #ifndef. */
|
||||
|
||||
|
||||
/* Some shorthands. */
|
||||
|
||||
# if defined (HPUX) && !defined (hpux)
|
||||
# define hpux
|
||||
# endif
|
||||
|
||||
# if defined (__hpux) && !defined (hpux)
|
||||
# define hpux
|
||||
# endif
|
||||
|
||||
# if defined (__sun) && !defined (sun)
|
||||
# define sun
|
||||
# endif
|
||||
|
||||
# if defined (hp300) && !defined (hpux)
|
||||
# define MORE_BSD
|
||||
# endif
|
||||
|
||||
# if defined (__SVR4) && !defined (SVR4)
|
||||
# define SVR4
|
||||
# endif
|
||||
|
||||
# if (defined (sun) && defined (SVR4)) || defined (SOLARIS2)
|
||||
# define SUNOS_5
|
||||
# endif
|
||||
|
||||
# if defined (__osf__) && (defined (__alpha) || defined (__alpha__))
|
||||
# define OSF_ALPHA
|
||||
# include <sys/mbuf.h>
|
||||
# include <sys/socket.h>
|
||||
# include <net/route.h>
|
||||
# include <sys/table.h>
|
||||
/* Tru64 4.0D's table.h redefines sys */
|
||||
# undef sys
|
||||
# endif
|
||||
|
||||
# if defined (__osf__) && (defined (mips) || defined (__mips__))
|
||||
# define OSF_MIPS
|
||||
# include <sys/table.h>
|
||||
# endif
|
||||
|
||||
|
||||
/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */
|
||||
# ifndef LOAD_AVE_TYPE
|
||||
|
||||
# ifdef MORE_BSD
|
||||
# define LOAD_AVE_TYPE long
|
||||
# endif
|
||||
|
||||
# ifdef sun
|
||||
# define LOAD_AVE_TYPE long
|
||||
# endif
|
||||
|
||||
# ifdef sgi
|
||||
# define LOAD_AVE_TYPE long
|
||||
# endif
|
||||
|
||||
# ifdef SVR4
|
||||
# define LOAD_AVE_TYPE long
|
||||
# endif
|
||||
|
||||
# ifdef OSF_ALPHA
|
||||
# define LOAD_AVE_TYPE long
|
||||
# endif
|
||||
|
||||
# if defined _AIX && ! defined HAVE_LIBPERFSTAT
|
||||
# define LOAD_AVE_TYPE long
|
||||
# endif
|
||||
|
||||
# endif /* No LOAD_AVE_TYPE. */
|
||||
|
||||
# ifdef OSF_ALPHA
|
||||
/* <sys/param.h> defines an incorrect value for FSCALE on Alpha OSF/1,
|
||||
according to ghazi@noc.rutgers.edu. */
|
||||
# undef FSCALE
|
||||
# define FSCALE 1024.0
|
||||
# endif
|
||||
|
||||
|
||||
# ifndef FSCALE
|
||||
|
||||
/* SunOS and some others define FSCALE in sys/param.h. */
|
||||
|
||||
# ifdef MORE_BSD
|
||||
# define FSCALE 2048.0
|
||||
# endif
|
||||
|
||||
# if defined (MIPS) || defined (SVR4)
|
||||
# define FSCALE 256
|
||||
# endif
|
||||
|
||||
# if defined (sgi)
|
||||
/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined
|
||||
above under #ifdef MIPS. But we want the sgi value. */
|
||||
# undef FSCALE
|
||||
# define FSCALE 1000.0
|
||||
# endif
|
||||
|
||||
# if defined _AIX && !defined HAVE_LIBPERFSTAT
|
||||
# define FSCALE 65536.0
|
||||
# endif
|
||||
|
||||
# endif /* Not FSCALE. */
|
||||
|
||||
# if !defined (LDAV_CVT) && defined (FSCALE)
|
||||
# define LDAV_CVT(n) (((double) (n)) / FSCALE)
|
||||
# endif
|
||||
|
||||
# ifndef NLIST_STRUCT
|
||||
# if HAVE_NLIST_H
|
||||
# define NLIST_STRUCT
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined (sgi) || (defined (mips) && !defined (BSD))
|
||||
# define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31))
|
||||
# endif
|
||||
|
||||
|
||||
# if !defined (KERNEL_FILE) && defined (hpux)
|
||||
# define KERNEL_FILE "/hp-ux"
|
||||
# endif
|
||||
|
||||
# if !defined (KERNEL_FILE) && (defined (MIPS) || defined (SVR4) || defined (ISC) || defined (sgi))
|
||||
# define KERNEL_FILE "/unix"
|
||||
# endif
|
||||
|
||||
|
||||
# if !defined (LDAV_SYMBOL) && (defined (hpux) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (_AIX) && !defined(HAVE_LIBPERFSTAT)))
|
||||
# define LDAV_SYMBOL "avenrun"
|
||||
# endif
|
||||
|
||||
# ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
|
||||
/* LOAD_AVE_TYPE should only get defined if we're going to use the
|
||||
nlist method. */
|
||||
# if !defined (LOAD_AVE_TYPE) && (defined (BSD) || defined (LDAV_CVT) || defined (KERNEL_FILE) || defined (LDAV_SYMBOL))
|
||||
# define LOAD_AVE_TYPE double
|
||||
# endif
|
||||
|
||||
# ifdef LOAD_AVE_TYPE
|
||||
|
||||
# ifndef __VMS
|
||||
# if !(defined __linux__ || defined __ANDROID__)
|
||||
# ifndef NLIST_STRUCT
|
||||
# include <a.out.h>
|
||||
# else /* NLIST_STRUCT */
|
||||
# include <nlist.h>
|
||||
# endif /* NLIST_STRUCT */
|
||||
|
||||
# ifdef SUNOS_5
|
||||
# include <kvm.h>
|
||||
# include <kstat.h>
|
||||
# endif
|
||||
|
||||
# if defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
|
||||
# include <sys/pstat.h>
|
||||
# endif
|
||||
|
||||
# ifndef KERNEL_FILE
|
||||
# define KERNEL_FILE "/vmunix"
|
||||
# endif /* KERNEL_FILE */
|
||||
|
||||
# ifndef LDAV_SYMBOL
|
||||
# define LDAV_SYMBOL "_avenrun"
|
||||
# endif /* LDAV_SYMBOL */
|
||||
# endif /* __linux__ || __ANDROID__ */
|
||||
|
||||
# else /* __VMS */
|
||||
|
||||
# ifndef eunice
|
||||
# include <iodef.h>
|
||||
# include <descrip.h>
|
||||
# else /* eunice */
|
||||
# include <vms/iodef.h>
|
||||
# endif /* eunice */
|
||||
# endif /* __VMS */
|
||||
|
||||
# ifndef LDAV_CVT
|
||||
# define LDAV_CVT(n) ((double) (n))
|
||||
# endif /* !LDAV_CVT */
|
||||
|
||||
# endif /* LOAD_AVE_TYPE */
|
||||
|
||||
# if defined HAVE_LIBPERFSTAT
|
||||
# include <sys/protosw.h>
|
||||
# include <libperfstat.h>
|
||||
# include <sys/proc.h>
|
||||
# ifndef SBITS
|
||||
# define SBITS 16
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined (__GNU__) && !defined (NeXT)
|
||||
/* Note that NeXT Openstep defines __GNU__ even though it should not. */
|
||||
/* GNU system acts much like NeXT, for load average purposes,
|
||||
but not exactly. */
|
||||
# define NeXT
|
||||
# define host_self mach_host_self
|
||||
# endif
|
||||
|
||||
# ifdef NeXT
|
||||
# ifdef HAVE_MACH_MACH_H
|
||||
# include <mach/mach.h>
|
||||
# else
|
||||
# include <mach.h>
|
||||
# endif
|
||||
# endif /* NeXT */
|
||||
|
||||
# ifdef sgi
|
||||
# include <sys/sysmp.h>
|
||||
# endif /* sgi */
|
||||
|
||||
# ifdef UMAX
|
||||
# include <signal.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/wait.h>
|
||||
# include <sys/syscall.h>
|
||||
|
||||
# ifdef UMAX_43
|
||||
# include <machine/cpu.h>
|
||||
# include <inq_stats/statistics.h>
|
||||
# include <inq_stats/sysstats.h>
|
||||
# include <inq_stats/cpustats.h>
|
||||
# include <inq_stats/procstats.h>
|
||||
# else /* Not UMAX_43. */
|
||||
# include <sys/sysdefs.h>
|
||||
# include <sys/statistics.h>
|
||||
# include <sys/sysstats.h>
|
||||
# include <sys/cpudefs.h>
|
||||
# include <sys/cpustats.h>
|
||||
# include <sys/procstats.h>
|
||||
# endif /* Not UMAX_43. */
|
||||
# endif /* UMAX */
|
||||
|
||||
# ifdef DGUX
|
||||
# include <sys/dg_sys_info.h>
|
||||
# endif
|
||||
|
||||
# if (defined __linux__ || defined __ANDROID__ \
|
||||
|| defined __CYGWIN__ || defined SUNOS_5 \
|
||||
|| (defined LOAD_AVE_TYPE && ! defined __VMS))
|
||||
# include <fcntl.h>
|
||||
# endif
|
||||
|
||||
/* Avoid static vars inside a function since in HPUX they dump as pure. */
|
||||
|
||||
# ifdef NeXT
|
||||
static processor_set_t default_set;
|
||||
static bool getloadavg_initialized;
|
||||
# endif /* NeXT */
|
||||
|
||||
# ifdef UMAX
|
||||
static unsigned int cpus = 0;
|
||||
static unsigned int samples;
|
||||
# endif /* UMAX */
|
||||
|
||||
# ifdef DGUX
|
||||
static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */
|
||||
# endif /* DGUX */
|
||||
|
||||
# if !defined (HAVE_LIBKSTAT) && defined (LOAD_AVE_TYPE)
|
||||
/* File descriptor open to /dev/kmem or VMS load ave driver. */
|
||||
static int channel;
|
||||
/* True if channel is valid. */
|
||||
static bool getloadavg_initialized;
|
||||
/* Offset in kmem to seek to read load average, or 0 means invalid. */
|
||||
static long offset;
|
||||
|
||||
# if ! defined __VMS && ! defined sgi && ! (defined __linux__ || defined __ANDROID__)
|
||||
static struct nlist name_list[2];
|
||||
# endif
|
||||
|
||||
# ifdef SUNOS_5
|
||||
static kvm_t *kd;
|
||||
# endif /* SUNOS_5 */
|
||||
|
||||
# endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */
|
||||
|
||||
/* Put the 1 minute, 5 minute and 15 minute load averages
|
||||
into the first NELEM elements of LOADAVG.
|
||||
Return the number written (never more than 3, but may be less than NELEM),
|
||||
or -1 (setting errno) if an error occurred. */
|
||||
|
||||
int
|
||||
getloadavg (double loadavg[], int nelem)
|
||||
{
|
||||
int elem = 0; /* Return value. */
|
||||
|
||||
# ifdef NO_GET_LOAD_AVG
|
||||
# define LDAV_DONE
|
||||
errno = ENOSYS;
|
||||
elem = -1;
|
||||
# endif
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) /* Solaris <= 2.6 */
|
||||
/* Use libkstat because we don't have to be root. */
|
||||
# define LDAV_DONE
|
||||
kstat_ctl_t *kc;
|
||||
kstat_t *ksp;
|
||||
kstat_named_t *kn;
|
||||
int saved_errno;
|
||||
|
||||
kc = kstat_open ();
|
||||
if (kc == NULL)
|
||||
return -1;
|
||||
ksp = kstat_lookup (kc, "unix", 0, "system_misc");
|
||||
if (ksp == NULL)
|
||||
return -1;
|
||||
if (kstat_read (kc, ksp, 0) == -1)
|
||||
return -1;
|
||||
|
||||
|
||||
kn = kstat_data_lookup (ksp, "avenrun_1min");
|
||||
if (kn == NULL)
|
||||
{
|
||||
/* Return -1 if no load average information is available. */
|
||||
nelem = 0;
|
||||
elem = -1;
|
||||
}
|
||||
|
||||
if (nelem >= 1)
|
||||
loadavg[elem++] = (double) kn->value.ul / FSCALE;
|
||||
|
||||
if (nelem >= 2)
|
||||
{
|
||||
kn = kstat_data_lookup (ksp, "avenrun_5min");
|
||||
if (kn != NULL)
|
||||
{
|
||||
loadavg[elem++] = (double) kn->value.ul / FSCALE;
|
||||
|
||||
if (nelem >= 3)
|
||||
{
|
||||
kn = kstat_data_lookup (ksp, "avenrun_15min");
|
||||
if (kn != NULL)
|
||||
loadavg[elem++] = (double) kn->value.ul / FSCALE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saved_errno = errno;
|
||||
kstat_close (kc);
|
||||
errno = saved_errno;
|
||||
# endif /* HAVE_LIBKSTAT */
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
|
||||
/* HP-UX */
|
||||
/* Use pstat_getdynamic() because we don't have to be root. */
|
||||
# define LDAV_DONE
|
||||
# undef LOAD_AVE_TYPE
|
||||
|
||||
struct pst_dynamic dyn_info;
|
||||
if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0)
|
||||
return -1;
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = dyn_info.psd_avg_1_min;
|
||||
if (nelem > 1)
|
||||
loadavg[elem++] = dyn_info.psd_avg_5_min;
|
||||
if (nelem > 2)
|
||||
loadavg[elem++] = dyn_info.psd_avg_15_min;
|
||||
|
||||
# endif /* hpux && HAVE_PSTAT_GETDYNAMIC */
|
||||
|
||||
# if ! defined LDAV_DONE && defined HAVE_LIBPERFSTAT /* AIX */
|
||||
# define LDAV_DONE
|
||||
# undef LOAD_AVE_TYPE
|
||||
/* Use perfstat_cpu_total because we don't have to be root. */
|
||||
{
|
||||
perfstat_cpu_total_t cpu_stats;
|
||||
int result = perfstat_cpu_total (NULL, &cpu_stats, sizeof cpu_stats, 1);
|
||||
if (result == -1)
|
||||
return result;
|
||||
loadavg[0] = cpu_stats.loadavg[0] / (double)(1 << SBITS);
|
||||
loadavg[1] = cpu_stats.loadavg[1] / (double)(1 << SBITS);
|
||||
loadavg[2] = cpu_stats.loadavg[2] / (double)(1 << SBITS);
|
||||
elem = 3;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__ || defined __CYGWIN__)
|
||||
/* Linux without glibc, Android, Cygwin */
|
||||
# define LDAV_DONE
|
||||
# undef LOAD_AVE_TYPE
|
||||
|
||||
# ifndef LINUX_LDAV_FILE
|
||||
# define LINUX_LDAV_FILE "/proc/loadavg"
|
||||
# endif
|
||||
|
||||
char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")];
|
||||
char const *ptr = ldavgbuf;
|
||||
int fd, count, saved_errno;
|
||||
|
||||
fd = open (LINUX_LDAV_FILE, O_RDONLY | O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
count = read (fd, ldavgbuf, sizeof ldavgbuf - 1);
|
||||
saved_errno = errno;
|
||||
(void) close (fd);
|
||||
errno = saved_errno;
|
||||
if (count <= 0)
|
||||
return -1;
|
||||
ldavgbuf[count] = '\0';
|
||||
|
||||
for (elem = 0; elem < nelem; elem++)
|
||||
{
|
||||
double numerator = 0;
|
||||
double denominator = 1;
|
||||
|
||||
while (*ptr == ' ')
|
||||
ptr++;
|
||||
|
||||
/* Finish if this number is missing, and report an error if all
|
||||
were missing. */
|
||||
if (! ('0' <= *ptr && *ptr <= '9'))
|
||||
{
|
||||
if (elem == 0)
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
while ('0' <= *ptr && *ptr <= '9')
|
||||
numerator = 10 * numerator + (*ptr++ - '0');
|
||||
|
||||
if (*ptr == '.')
|
||||
for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++)
|
||||
numerator = 10 * numerator + (*ptr - '0'), denominator *= 10;
|
||||
|
||||
loadavg[elem] = numerator / denominator;
|
||||
}
|
||||
|
||||
return elem;
|
||||
|
||||
# endif /* __linux__ || __ANDROID__ || __CYGWIN__ */
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */
|
||||
# define LDAV_DONE
|
||||
# undef LOAD_AVE_TYPE
|
||||
|
||||
# ifndef NETBSD_LDAV_FILE
|
||||
# define NETBSD_LDAV_FILE "/kern/loadavg"
|
||||
# endif
|
||||
|
||||
unsigned long int load_ave[3], scale;
|
||||
int count;
|
||||
char readbuf[4 * INT_BUFSIZE_BOUND (unsigned long int) + 1];
|
||||
int fd = open (NETBSD_LDAV_FILE, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
int nread = read (fd, readbuf, sizeof readbuf - 1);
|
||||
int err = errno;
|
||||
close (fd);
|
||||
if (nread < 0)
|
||||
{
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
readbuf[nread] = '\0';
|
||||
count = sscanf (readbuf, "%lu %lu %lu %lu\n",
|
||||
&load_ave[0], &load_ave[1], &load_ave[2],
|
||||
&scale);
|
||||
if (count != 4)
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (elem = 0; elem < nelem; elem++)
|
||||
loadavg[elem] = (double) load_ave[elem] / (double) scale;
|
||||
|
||||
return elem;
|
||||
|
||||
# endif /* __NetBSD__ */
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (NeXT) /* NeXTStep */
|
||||
# define LDAV_DONE
|
||||
/* The NeXT code was adapted from iscreen 3.2. */
|
||||
|
||||
host_t host;
|
||||
struct processor_set_basic_info info;
|
||||
unsigned int info_count;
|
||||
|
||||
/* We only know how to get the 1-minute average for this system,
|
||||
so even if the caller asks for more than 1, we only return 1. */
|
||||
|
||||
if (!getloadavg_initialized)
|
||||
{
|
||||
if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
|
||||
getloadavg_initialized = true;
|
||||
}
|
||||
|
||||
if (getloadavg_initialized)
|
||||
{
|
||||
info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
|
||||
if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
|
||||
(processor_set_info_t) &info, &info_count)
|
||||
!= KERN_SUCCESS)
|
||||
getloadavg_initialized = false;
|
||||
else
|
||||
{
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!getloadavg_initialized)
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
# endif /* NeXT */
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (UMAX)
|
||||
# define LDAV_DONE
|
||||
/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
|
||||
have a /dev/kmem. Information about the workings of the running kernel
|
||||
can be gathered with inq_stats system calls.
|
||||
We only know how to get the 1-minute average for this system. */
|
||||
|
||||
struct proc_summary proc_sum_data;
|
||||
struct stat_descr proc_info;
|
||||
double load;
|
||||
register unsigned int i, j;
|
||||
|
||||
if (cpus == 0)
|
||||
{
|
||||
register unsigned int c, i;
|
||||
struct cpu_config conf;
|
||||
struct stat_descr desc;
|
||||
|
||||
desc.sd_next = 0;
|
||||
desc.sd_subsys = SUBSYS_CPU;
|
||||
desc.sd_type = CPUTYPE_CONFIG;
|
||||
desc.sd_addr = (char *) &conf;
|
||||
desc.sd_size = sizeof conf;
|
||||
|
||||
if (inq_stats (1, &desc))
|
||||
return -1;
|
||||
|
||||
c = 0;
|
||||
for (i = 0; i < conf.config_maxclass; ++i)
|
||||
{
|
||||
struct class_stats stats;
|
||||
memset (&stats, 0, sizeof stats);
|
||||
|
||||
desc.sd_type = CPUTYPE_CLASS;
|
||||
desc.sd_objid = i;
|
||||
desc.sd_addr = (char *) &stats;
|
||||
desc.sd_size = sizeof stats;
|
||||
|
||||
if (inq_stats (1, &desc))
|
||||
return -1;
|
||||
|
||||
c += stats.class_numcpus;
|
||||
}
|
||||
cpus = c;
|
||||
samples = cpus < 2 ? 3 : (2 * cpus / 3);
|
||||
}
|
||||
|
||||
proc_info.sd_next = 0;
|
||||
proc_info.sd_subsys = SUBSYS_PROC;
|
||||
proc_info.sd_type = PROCTYPE_SUMMARY;
|
||||
proc_info.sd_addr = (char *) &proc_sum_data;
|
||||
proc_info.sd_size = sizeof (struct proc_summary);
|
||||
proc_info.sd_sizeused = 0;
|
||||
|
||||
if (inq_stats (1, &proc_info) != 0)
|
||||
return -1;
|
||||
|
||||
load = proc_sum_data.ps_nrunnable;
|
||||
j = 0;
|
||||
for (i = samples - 1; i > 0; --i)
|
||||
{
|
||||
load += proc_sum_data.ps_nrun[j];
|
||||
if (j++ == PS_NRUNSIZE)
|
||||
j = 0;
|
||||
}
|
||||
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = load / samples / cpus;
|
||||
# endif /* UMAX */
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (DGUX)
|
||||
# define LDAV_DONE
|
||||
/* This call can return -1 for an error, but with good args
|
||||
it's not supposed to fail. The first argument is for no
|
||||
apparent reason of type 'long int *'. */
|
||||
dg_sys_info ((long int *) &load_info,
|
||||
DG_SYS_INFO_LOAD_INFO_TYPE,
|
||||
DG_SYS_INFO_LOAD_VERSION_0);
|
||||
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = load_info.one_minute;
|
||||
if (nelem > 1)
|
||||
loadavg[elem++] = load_info.five_minute;
|
||||
if (nelem > 2)
|
||||
loadavg[elem++] = load_info.fifteen_minute;
|
||||
# endif /* DGUX */
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (apollo)
|
||||
# define LDAV_DONE
|
||||
/* Apollo code from lisch@mentorg.com (Ray Lischner).
|
||||
|
||||
This system call is not documented. The load average is obtained as
|
||||
three long integers, for the load average over the past minute,
|
||||
five minutes, and fifteen minutes. Each value is a scaled integer,
|
||||
with 16 bits of integer part and 16 bits of fraction part.
|
||||
|
||||
I'm not sure which operating system first supported this system call,
|
||||
but I know that SR10.2 supports it. */
|
||||
|
||||
extern void proc1_$get_loadav ();
|
||||
unsigned long load_ave[3];
|
||||
|
||||
proc1_$get_loadav (load_ave);
|
||||
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = load_ave[0] / 65536.0;
|
||||
if (nelem > 1)
|
||||
loadavg[elem++] = load_ave[1] / 65536.0;
|
||||
if (nelem > 2)
|
||||
loadavg[elem++] = load_ave[2] / 65536.0;
|
||||
# endif /* apollo */
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (OSF_MIPS)
|
||||
# define LDAV_DONE
|
||||
|
||||
struct tbl_loadavg load_ave;
|
||||
table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
|
||||
loadavg[elem++]
|
||||
= (load_ave.tl_lscale == 0
|
||||
? load_ave.tl_avenrun.d[0]
|
||||
: (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
|
||||
# endif /* OSF_MIPS */
|
||||
|
||||
# if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32))
|
||||
/* DJGPP */
|
||||
# define LDAV_DONE
|
||||
|
||||
/* A faithful emulation is going to have to be saved for a rainy day. */
|
||||
for ( ; elem < nelem; elem++)
|
||||
{
|
||||
loadavg[elem] = 0.0;
|
||||
}
|
||||
# endif /* __MSDOS__ || WINDOWS32 */
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (OSF_ALPHA) /* OSF/1 */
|
||||
# define LDAV_DONE
|
||||
|
||||
struct tbl_loadavg load_ave;
|
||||
table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
|
||||
for (elem = 0; elem < nelem; elem++)
|
||||
loadavg[elem]
|
||||
= (load_ave.tl_lscale == 0
|
||||
? load_ave.tl_avenrun.d[elem]
|
||||
: (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
|
||||
# endif /* OSF_ALPHA */
|
||||
|
||||
# if ! defined LDAV_DONE && defined __VMS /* VMS */
|
||||
/* VMS specific code -- read from the Load Ave driver. */
|
||||
|
||||
LOAD_AVE_TYPE load_ave[3];
|
||||
static bool getloadavg_initialized;
|
||||
# ifdef eunice
|
||||
struct
|
||||
{
|
||||
int dsc$w_length;
|
||||
char *dsc$a_pointer;
|
||||
} descriptor;
|
||||
# endif
|
||||
|
||||
/* Ensure that there is a channel open to the load ave device. */
|
||||
if (!getloadavg_initialized)
|
||||
{
|
||||
/* Attempt to open the channel. */
|
||||
# ifdef eunice
|
||||
descriptor.dsc$w_length = 18;
|
||||
descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE";
|
||||
# else
|
||||
$DESCRIPTOR (descriptor, "LAV0:");
|
||||
# endif
|
||||
if (sys$assign (&descriptor, &channel, 0, 0) & 1)
|
||||
getloadavg_initialized = true;
|
||||
}
|
||||
|
||||
/* Read the load average vector. */
|
||||
if (getloadavg_initialized
|
||||
&& !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0,
|
||||
load_ave, 12, 0, 0, 0, 0) & 1))
|
||||
{
|
||||
sys$dassgn (channel);
|
||||
getloadavg_initialized = false;
|
||||
}
|
||||
|
||||
if (!getloadavg_initialized)
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
# endif /* ! defined LDAV_DONE && defined __VMS */
|
||||
|
||||
# if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS
|
||||
/* IRIX, other old systems */
|
||||
|
||||
/* UNIX-specific code -- read the average from /dev/kmem. */
|
||||
|
||||
# define LDAV_PRIVILEGED /* This code requires special installation. */
|
||||
|
||||
LOAD_AVE_TYPE load_ave[3];
|
||||
|
||||
/* Get the address of LDAV_SYMBOL. */
|
||||
if (offset == 0)
|
||||
{
|
||||
# ifndef sgi
|
||||
# if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER
|
||||
strcpy (name_list[0].n_name, LDAV_SYMBOL);
|
||||
strcpy (name_list[1].n_name, "");
|
||||
# else /* NLIST_STRUCT */
|
||||
# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
|
||||
name_list[0].n_un.n_name = LDAV_SYMBOL;
|
||||
name_list[1].n_un.n_name = 0;
|
||||
# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
|
||||
name_list[0].n_name = LDAV_SYMBOL;
|
||||
name_list[1].n_name = 0;
|
||||
# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
|
||||
# endif /* NLIST_STRUCT */
|
||||
|
||||
# ifndef SUNOS_5
|
||||
if (
|
||||
# if !defined (_AIX)
|
||||
nlist (KERNEL_FILE, name_list)
|
||||
# else /* _AIX */
|
||||
knlist (name_list, 1, sizeof (name_list[0]))
|
||||
# endif
|
||||
>= 0)
|
||||
/* Omit "&& name_list[0].n_type != 0 " -- it breaks on Sun386i. */
|
||||
{
|
||||
# ifdef FIXUP_KERNEL_SYMBOL_ADDR
|
||||
FIXUP_KERNEL_SYMBOL_ADDR (name_list);
|
||||
# endif
|
||||
offset = name_list[0].n_value;
|
||||
}
|
||||
# endif /* !SUNOS_5 */
|
||||
# else /* sgi */
|
||||
ptrdiff_t ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
|
||||
if (ldav_off != -1)
|
||||
offset = (long int) ldav_off & 0x7fffffff;
|
||||
# endif /* sgi */
|
||||
}
|
||||
|
||||
/* Make sure we have /dev/kmem open. */
|
||||
if (!getloadavg_initialized)
|
||||
{
|
||||
# ifndef SUNOS_5
|
||||
int fd = open ("/dev/kmem", O_RDONLY | O_CLOEXEC);
|
||||
if (0 <= fd)
|
||||
{
|
||||
channel = fd;
|
||||
getloadavg_initialized = true;
|
||||
}
|
||||
# else /* SUNOS_5 */
|
||||
/* We pass 0 for the kernel, corefile, and swapfile names
|
||||
to use the currently running kernel. */
|
||||
kd = kvm_open (0, 0, 0, O_RDONLY, 0);
|
||||
if (kd != NULL)
|
||||
{
|
||||
/* nlist the currently running kernel. */
|
||||
kvm_nlist (kd, name_list);
|
||||
offset = name_list[0].n_value;
|
||||
getloadavg_initialized = true;
|
||||
}
|
||||
# endif /* SUNOS_5 */
|
||||
}
|
||||
|
||||
/* If we can, get the load average values. */
|
||||
if (offset && getloadavg_initialized)
|
||||
{
|
||||
/* Try to read the load. */
|
||||
# ifndef SUNOS_5
|
||||
if (lseek (channel, offset, 0) == -1L
|
||||
|| read (channel, (char *) load_ave, sizeof (load_ave))
|
||||
!= sizeof (load_ave))
|
||||
{
|
||||
close (channel);
|
||||
getloadavg_initialized = false;
|
||||
}
|
||||
# else /* SUNOS_5 */
|
||||
if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
|
||||
!= sizeof (load_ave))
|
||||
{
|
||||
kvm_close (kd);
|
||||
getloadavg_initialized = false;
|
||||
}
|
||||
# endif /* SUNOS_5 */
|
||||
}
|
||||
|
||||
if (offset == 0 || !getloadavg_initialized)
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
# endif /* ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS */
|
||||
|
||||
# if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = LDAV_CVT (load_ave[0]);
|
||||
if (nelem > 1)
|
||||
loadavg[elem++] = LDAV_CVT (load_ave[1]);
|
||||
if (nelem > 2)
|
||||
loadavg[elem++] = LDAV_CVT (load_ave[2]);
|
||||
|
||||
# define LDAV_DONE
|
||||
# endif /* !LDAV_DONE && LOAD_AVE_TYPE */
|
||||
|
||||
# if !defined LDAV_DONE
|
||||
errno = ENOSYS;
|
||||
elem = -1;
|
||||
# endif
|
||||
return elem;
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/* getopt-on-non-glibc compatibility macros.
|
||||
Copyright (C) 1989-2023 Free Software Foundation, Inc.
|
||||
This file is part of gnulib.
|
||||
Unlike most of the getopt implementation, it is NOT shared
|
||||
with the GNU C Library.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GETOPT_CDEFS_H
|
||||
#define _GETOPT_CDEFS_H 1
|
||||
|
||||
/* This header should not be used directly; include getopt.h or
|
||||
unistd.h instead. It does not have a protective #error, because
|
||||
the guard macro for getopt.h in gnulib is not fixed. */
|
||||
|
||||
/* getopt-core.h and getopt-ext.h are shared with GNU libc, and expect
|
||||
a number of the internal macros supplied to GNU libc's headers by
|
||||
sys/cdefs.h. Provide fallback definitions for all of them. */
|
||||
#if @HAVE_SYS_CDEFS_H@
|
||||
# include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
#ifndef __BEGIN_DECLS
|
||||
# ifdef __cplusplus
|
||||
# define __BEGIN_DECLS extern "C" {
|
||||
# else
|
||||
# define __BEGIN_DECLS /* nothing */
|
||||
# endif
|
||||
#endif
|
||||
#ifndef __END_DECLS
|
||||
# ifdef __cplusplus
|
||||
# define __END_DECLS }
|
||||
# else
|
||||
# define __END_DECLS /* nothing */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC_PREREQ
|
||||
# if defined __GNUC__ && defined __GNUC_VERSION__
|
||||
# define __GNUC_PREREQ(maj, min) \
|
||||
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
||||
# else
|
||||
# define __GNUC_PREREQ(maj, min) 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef __THROW
|
||||
# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major__ >= 4)
|
||||
# define __THROW throw ()
|
||||
# else
|
||||
# define __THROW
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_CDEFS_H */
|
|
@ -1,96 +0,0 @@
|
|||
/* Declarations for getopt (basic, portable features only).
|
||||
Copyright (C) 1989-2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library and is also part of gnulib.
|
||||
Patches to this file should be submitted to both projects.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GETOPT_CORE_H
|
||||
#define _GETOPT_CORE_H 1
|
||||
|
||||
/* This header should not be used directly; include getopt.h or
|
||||
unistd.h instead. Unlike most bits headers, it does not have
|
||||
a protective #error, because the guard macro for getopt.h in
|
||||
gnulib is not fixed. */
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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.
|
||||
|
||||
For standards compliance, the 'argv' argument has the type
|
||||
char *const *, but this is inaccurate; if argument permutation is
|
||||
enabled, the argv array (not the strings it points to) must be
|
||||
writable. */
|
||||
|
||||
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
|
||||
__THROW _GL_ARG_NONNULL ((2, 3));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _GETOPT_CORE_H */
|
|
@ -1,77 +0,0 @@
|
|||
/* Declarations for getopt (GNU extensions).
|
||||
Copyright (C) 1989-2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library and is also part of gnulib.
|
||||
Patches to this file should be submitted to both projects.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GETOPT_EXT_H
|
||||
#define _GETOPT_EXT_H 1
|
||||
|
||||
/* This header should not be used directly; include getopt.h instead.
|
||||
Unlike most bits headers, it does not have a protective #error,
|
||||
because the guard macro for getopt.h in gnulib is not fixed. */
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* 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
|
||||
|
||||
extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind)
|
||||
__THROW _GL_ARG_NONNULL ((2, 3));
|
||||
extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind)
|
||||
__THROW _GL_ARG_NONNULL ((2, 3));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _GETOPT_EXT_H */
|
|
@ -1,66 +0,0 @@
|
|||
/* getopt (basic, portable features) gnulib wrapper header.
|
||||
Copyright (C) 1989-2023 Free Software Foundation, Inc.
|
||||
This file is part of gnulib.
|
||||
Unlike most of the getopt implementation, it is NOT shared
|
||||
with the GNU C Library.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GETOPT_PFX_CORE_H
|
||||
#define _GETOPT_PFX_CORE_H 1
|
||||
|
||||
/* This header should not be used directly; include getopt.h or
|
||||
unistd.h instead. It does not have a protective #error, because
|
||||
the guard macro for getopt.h in gnulib is not fixed. */
|
||||
|
||||
/* Standalone applications should #define __GETOPT_PREFIX to an
|
||||
identifier that prefixes the external functions and variables
|
||||
defined in getopt-core.h and getopt-ext.h. Systematically
|
||||
rename identifiers so that they do not collide with the system
|
||||
functions and variables. Renaming avoids problems with some
|
||||
compilers and linkers. */
|
||||
#ifdef __GETOPT_PREFIX
|
||||
# ifndef __GETOPT_ID
|
||||
# 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)
|
||||
# endif
|
||||
# undef getopt
|
||||
# undef optarg
|
||||
# undef opterr
|
||||
# undef optind
|
||||
# undef optopt
|
||||
# define getopt __GETOPT_ID (getopt)
|
||||
# define optarg __GETOPT_ID (optarg)
|
||||
# define opterr __GETOPT_ID (opterr)
|
||||
# define optind __GETOPT_ID (optind)
|
||||
# define optopt __GETOPT_ID (optopt)
|
||||
|
||||
/* Work around a problem on macOS, which declares getopt with a
|
||||
trailing __DARWIN_ALIAS(getopt) that would expand to something like
|
||||
__asm("_" "rpl_getopt" "$UNIX2003") were it not for the following
|
||||
hack to suppress the macOS declaration <https://bugs.gnu.org/40205>. */
|
||||
# ifdef __APPLE__
|
||||
# define _GETOPT
|
||||
# endif
|
||||
|
||||
/* The system's getopt.h may have already included getopt-core.h to
|
||||
declare the unprefixed identifiers. Undef _GETOPT_CORE_H so that
|
||||
getopt-core.h declares them with prefixes. */
|
||||
# undef _GETOPT_CORE_H
|
||||
#endif
|
||||
|
||||
#include <getopt-core.h>
|
||||
|
||||
#endif /* _GETOPT_PFX_CORE_H */
|
|
@ -1,70 +0,0 @@
|
|||
/* getopt (GNU extensions) gnulib wrapper header.
|
||||
Copyright (C) 1989-2023 Free Software Foundation, Inc.
|
||||
This file is part of gnulib.
|
||||
Unlike most of the getopt implementation, it is NOT shared
|
||||
with the GNU C Library.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GETOPT_PFX_EXT_H
|
||||
#define _GETOPT_PFX_EXT_H 1
|
||||
|
||||
/* This header should not be used directly; include getopt.h instead.
|
||||
It does not have a protective #error, because the guard macro for
|
||||
getopt.h in gnulib is not fixed. */
|
||||
|
||||
/* Standalone applications should #define __GETOPT_PREFIX to an
|
||||
identifier that prefixes the external functions and variables
|
||||
defined in getopt-core.h and getopt-ext.h. Systematically
|
||||
rename identifiers so that they do not collide with the system
|
||||
functions and variables. Renaming avoids problems with some
|
||||
compilers and linkers. */
|
||||
#ifdef __GETOPT_PREFIX
|
||||
# ifndef __GETOPT_ID
|
||||
# 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)
|
||||
# endif
|
||||
# undef getopt_long
|
||||
# undef getopt_long_only
|
||||
# undef option
|
||||
# undef _getopt_internal
|
||||
# define getopt_long __GETOPT_ID (getopt_long)
|
||||
# define getopt_long_only __GETOPT_ID (getopt_long_only)
|
||||
# define option __GETOPT_ID (option)
|
||||
# define _getopt_internal __GETOPT_ID (getopt_internal)
|
||||
|
||||
/* The system's getopt.h may have already included getopt-ext.h to
|
||||
declare the unprefixed identifiers. Undef _GETOPT_EXT_H so that
|
||||
getopt-ext.h declares them with prefixes. */
|
||||
# undef _GETOPT_EXT_H
|
||||
#endif
|
||||
|
||||
/* Standalone applications get correct prototypes for getopt_long and
|
||||
getopt_long_only; they declare "char **argv". For backward
|
||||
compatibility with old applications, if __GETOPT_PREFIX is not
|
||||
defined, we supply GNU-libc-compatible, but incorrect, prototypes
|
||||
using "char *const *argv". (GNU libc is stuck with the incorrect
|
||||
prototypes, as they are baked into older versions of LSB.) */
|
||||
#ifndef __getopt_argv_const
|
||||
# if defined __GETOPT_PREFIX
|
||||
# define __getopt_argv_const /* empty */
|
||||
# else
|
||||
# define __getopt_argv_const const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <getopt-ext.h>
|
||||
|
||||
#endif /* _GETOPT_PFX_EXT_H */
|
|
@ -1,811 +0,0 @@
|
|||
/* Getopt for GNU.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library and is also part of gnulib.
|
||||
Patches to this file should be submitted to both projects.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _LIBC
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
/* When used as part of glibc, error printing must be done differently
|
||||
for standards compliance. getopt is not a cancellation point, so
|
||||
it must not call functions that are, and it is specified by an
|
||||
older standard than stdio locking, so it must not refer to
|
||||
functions in the "user namespace" related to stdio locking.
|
||||
Finally, it must use glibc's internal message translation so that
|
||||
the messages are looked up in the proper text domain. */
|
||||
# include <libintl.h>
|
||||
# define fprintf __fxprintf_nocancel
|
||||
# define flockfile(fp) _IO_flockfile (fp)
|
||||
# define funlockfile(fp) _IO_funlockfile (fp)
|
||||
#else
|
||||
# include "gettext.h"
|
||||
# define _(msgid) gettext (msgid)
|
||||
/* When used standalone, flockfile and funlockfile might not be
|
||||
available. */
|
||||
# if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \
|
||||
|| (defined _WIN32 && ! defined __CYGWIN__))
|
||||
# define flockfile(fp) /* nop */
|
||||
# define funlockfile(fp) /* nop */
|
||||
# endif
|
||||
/* When used standalone, do not attempt to use alloca. */
|
||||
# define __libc_use_alloca(size) 0
|
||||
# undef alloca
|
||||
# define alloca(size) (abort (), (void *)0)
|
||||
#endif
|
||||
|
||||
/* This implementation of 'getopt' has three modes for handling
|
||||
options interspersed with non-option arguments. It can stop
|
||||
scanning for options at the first non-option argument encountered,
|
||||
as POSIX specifies. It can continue scanning for options after the
|
||||
first non-option argument, but permute 'argv' as it goes so that,
|
||||
after 'getopt' is done, all the options precede all the non-option
|
||||
arguments and 'optind' points to the first non-option argument.
|
||||
Or, it can report non-option arguments as if they were arguments to
|
||||
the option character '\x01'.
|
||||
|
||||
The default behavior of 'getopt_long' is to permute the argument list.
|
||||
When this implementation is used standalone, the default behavior of
|
||||
'getopt' is to stop at the first non-option argument, but when it is
|
||||
used as part of GNU libc it also permutes the argument list. In both
|
||||
cases, setting the environment variable POSIXLY_CORRECT to any value
|
||||
disables permutation.
|
||||
|
||||
If the first character of the OPTSTRING argument to 'getopt' or
|
||||
'getopt_long' is '+', both functions will stop at the first
|
||||
non-option argument. If it is '-', both functions will report
|
||||
non-option arguments as arguments to the option character '\x01'. */
|
||||
|
||||
#include "getopt_int.h"
|
||||
|
||||
/* 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. */
|
||||
|
||||
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. */
|
||||
|
||||
/* 1003.2 says this must be 1 before any call. */
|
||||
int optind = 1;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
int optopt = '?';
|
||||
|
||||
/* Keep a global copy of all internal members of getopt_data. */
|
||||
|
||||
static struct _getopt_data getopt_data;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
'first_nonopt' and 'last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (char **argv, struct _getopt_data *d)
|
||||
{
|
||||
int bottom = d->__first_nonopt;
|
||||
int middle = d->__last_nonopt;
|
||||
int top = d->optind;
|
||||
char *tem;
|
||||
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
but it consists of two parts that need to be swapped next. */
|
||||
|
||||
while (top > middle && middle > bottom)
|
||||
{
|
||||
if (top - middle > middle - bottom)
|
||||
{
|
||||
/* Bottom segment is the short one. */
|
||||
int len = middle - bottom;
|
||||
int i;
|
||||
|
||||
/* Swap it with the top part of the top segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||
argv[top - (middle - bottom) + i] = tem;
|
||||
}
|
||||
/* Exclude the moved bottom segment from further swapping. */
|
||||
top -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Top segment is the short one. */
|
||||
int len = top - middle;
|
||||
int i;
|
||||
|
||||
/* Swap it with the bottom part of the bottom segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[middle + i];
|
||||
argv[middle + i] = tem;
|
||||
}
|
||||
/* Exclude the moved top segment from further swapping. */
|
||||
bottom += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
d->__first_nonopt += (d->optind - d->__last_nonopt);
|
||||
d->__last_nonopt = d->optind;
|
||||
}
|
||||
|
||||
/* Process the argument starting with d->__nextchar as a long option.
|
||||
d->optind should *not* have been advanced over this argument.
|
||||
|
||||
If the value returned is -1, it was not actually a long option, the
|
||||
state is unchanged, and the argument should be processed as a set
|
||||
of short options (this can only happen when long_only is true).
|
||||
Otherwise, the option (and its argument, if any) have been consumed
|
||||
and the return value is the value to return from _getopt_internal_r. */
|
||||
static int
|
||||
process_long_option (int argc, char **argv, const char *optstring,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only, struct _getopt_data *d,
|
||||
int print_errors, const char *prefix)
|
||||
{
|
||||
char *nameend;
|
||||
size_t namelen;
|
||||
const struct option *p;
|
||||
const struct option *pfound = NULL;
|
||||
int n_options;
|
||||
int option_index;
|
||||
|
||||
for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
namelen = nameend - d->__nextchar;
|
||||
|
||||
/* First look for an exact match, counting the options as a side
|
||||
effect. */
|
||||
for (p = longopts, n_options = 0; p->name; p++, n_options++)
|
||||
if (!strncmp (p->name, d->__nextchar, namelen)
|
||||
&& namelen == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
option_index = n_options;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pfound == NULL)
|
||||
{
|
||||
/* Didn't find an exact match, so look for abbreviations. */
|
||||
unsigned char *ambig_set = NULL;
|
||||
int ambig_malloced = 0;
|
||||
int ambig_fallback = 0;
|
||||
int indfound = -1;
|
||||
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!strncmp (p->name, d->__nextchar, namelen))
|
||||
{
|
||||
if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else if (long_only
|
||||
|| pfound->has_arg != p->has_arg
|
||||
|| pfound->flag != p->flag
|
||||
|| pfound->val != p->val)
|
||||
{
|
||||
/* Second or later nonexact match found. */
|
||||
if (!ambig_fallback)
|
||||
{
|
||||
if (!print_errors)
|
||||
/* Don't waste effort tracking the ambig set if
|
||||
we're not going to print it anyway. */
|
||||
ambig_fallback = 1;
|
||||
else if (!ambig_set)
|
||||
{
|
||||
if (__libc_use_alloca (n_options))
|
||||
ambig_set = alloca (n_options);
|
||||
else if ((ambig_set = malloc (n_options)) == NULL)
|
||||
/* Fall back to simpler error message. */
|
||||
ambig_fallback = 1;
|
||||
else
|
||||
ambig_malloced = 1;
|
||||
|
||||
if (ambig_set)
|
||||
{
|
||||
memset (ambig_set, 0, n_options);
|
||||
ambig_set[indfound] = 1;
|
||||
}
|
||||
}
|
||||
if (ambig_set)
|
||||
ambig_set[option_index] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ambig_set || ambig_fallback)
|
||||
{
|
||||
if (print_errors)
|
||||
{
|
||||
if (ambig_fallback)
|
||||
fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"),
|
||||
argv[0], prefix, d->__nextchar);
|
||||
else
|
||||
{
|
||||
flockfile (stderr);
|
||||
fprintf (stderr,
|
||||
_("%s: option '%s%s' is ambiguous; possibilities:"),
|
||||
argv[0], prefix, d->__nextchar);
|
||||
|
||||
for (option_index = 0; option_index < n_options; option_index++)
|
||||
if (ambig_set[option_index])
|
||||
fprintf (stderr, " '%s%s'",
|
||||
prefix, longopts[option_index].name);
|
||||
|
||||
/* This must use 'fprintf' even though it's only
|
||||
printing a single character, so that it goes through
|
||||
__fxprintf_nocancel when compiled as part of glibc. */
|
||||
fprintf (stderr, "\n");
|
||||
funlockfile (stderr);
|
||||
}
|
||||
}
|
||||
if (ambig_malloced)
|
||||
free (ambig_set);
|
||||
d->__nextchar += strlen (d->__nextchar);
|
||||
d->optind++;
|
||||
d->optopt = 0;
|
||||
return '?';
|
||||
}
|
||||
|
||||
option_index = indfound;
|
||||
}
|
||||
|
||||
if (pfound == NULL)
|
||||
{
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short option,
|
||||
then it's an error. */
|
||||
if (!long_only || argv[d->optind][1] == '-'
|
||||
|| strchr (optstring, *d->__nextchar) == NULL)
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr, _("%s: unrecognized option '%s%s'\n"),
|
||||
argv[0], prefix, d->__nextchar);
|
||||
|
||||
d->__nextchar = NULL;
|
||||
d->optind++;
|
||||
d->optopt = 0;
|
||||
return '?';
|
||||
}
|
||||
|
||||
/* Otherwise interpret it as a short option. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We have found a matching long option. Consume it. */
|
||||
d->optind++;
|
||||
d->__nextchar = NULL;
|
||||
if (*nameend)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
d->optarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr,
|
||||
_("%s: option '%s%s' doesn't allow an argument\n"),
|
||||
argv[0], prefix, pfound->name);
|
||||
|
||||
d->optopt = pfound->val;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (d->optind < argc)
|
||||
d->optarg = argv[d->optind++];
|
||||
else
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr,
|
||||
_("%s: option '%s%s' requires an argument\n"),
|
||||
argv[0], prefix, pfound->name);
|
||||
|
||||
d->optopt = pfound->val;
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
|
||||
/* Initialize internal data upon the first call to getopt. */
|
||||
|
||||
static const char *
|
||||
_getopt_initialize (_GL_UNUSED int argc,
|
||||
_GL_UNUSED char **argv, const char *optstring,
|
||||
struct _getopt_data *d, int posixly_correct)
|
||||
{
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
if (d->optind == 0)
|
||||
d->optind = 1;
|
||||
|
||||
d->__first_nonopt = d->__last_nonopt = d->optind;
|
||||
d->__nextchar = NULL;
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
d->__ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
d->__ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (posixly_correct || !!getenv ("POSIXLY_CORRECT"))
|
||||
d->__ordering = REQUIRE_ORDER;
|
||||
else
|
||||
d->__ordering = PERMUTE;
|
||||
|
||||
d->__initialized = 1;
|
||||
return optstring;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If 'getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If 'getopt' finds another option character, it returns that character,
|
||||
updating 'optind' and 'nextchar' so that the next call to 'getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, 'getopt' returns -1.
|
||||
Then 'optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set 'opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in 'optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in 'optarg', otherwise 'optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with '-' or '+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with '--' instead of '-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a '=', or else the in next ARGV-element.
|
||||
When 'getopt' finds a long-named option, it returns 0 if that option's
|
||||
'flag' field is nonzero, the value of the option's 'val' field
|
||||
if the 'flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of 'struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal_r (int argc, char **argv, const char *optstring,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only, struct _getopt_data *d, int posixly_correct)
|
||||
{
|
||||
int print_errors = d->opterr;
|
||||
|
||||
if (argc < 1)
|
||||
return -1;
|
||||
|
||||
d->optarg = NULL;
|
||||
|
||||
if (d->optind == 0 || !d->__initialized)
|
||||
optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct);
|
||||
else if (optstring[0] == '-' || optstring[0] == '+')
|
||||
optstring++;
|
||||
|
||||
if (optstring[0] == ':')
|
||||
print_errors = 0;
|
||||
|
||||
/* Test whether ARGV[optind] points to a non-option argument. */
|
||||
#define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
|
||||
|
||||
if (d->__nextchar == NULL || *d->__nextchar == '\0')
|
||||
{
|
||||
/* Advance to the next ARGV-element. */
|
||||
|
||||
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
|
||||
moved back by the user (who may also have changed the arguments). */
|
||||
if (d->__last_nonopt > d->optind)
|
||||
d->__last_nonopt = d->optind;
|
||||
if (d->__first_nonopt > d->optind)
|
||||
d->__first_nonopt = d->optind;
|
||||
|
||||
if (d->__ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (d->__first_nonopt != d->__last_nonopt
|
||||
&& d->__last_nonopt != d->optind)
|
||||
exchange (argv, d);
|
||||
else if (d->__last_nonopt != d->optind)
|
||||
d->__first_nonopt = d->optind;
|
||||
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (d->optind < argc && NONOPTION_P)
|
||||
d->optind++;
|
||||
d->__last_nonopt = d->optind;
|
||||
}
|
||||
|
||||
/* The special ARGV-element '--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (d->optind != argc && !strcmp (argv[d->optind], "--"))
|
||||
{
|
||||
d->optind++;
|
||||
|
||||
if (d->__first_nonopt != d->__last_nonopt
|
||||
&& d->__last_nonopt != d->optind)
|
||||
exchange (argv, d);
|
||||
else if (d->__first_nonopt == d->__last_nonopt)
|
||||
d->__first_nonopt = d->optind;
|
||||
d->__last_nonopt = argc;
|
||||
|
||||
d->optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (d->optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (d->__first_nonopt != d->__last_nonopt)
|
||||
d->optind = d->__first_nonopt;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if (NONOPTION_P)
|
||||
{
|
||||
if (d->__ordering == REQUIRE_ORDER)
|
||||
return -1;
|
||||
d->optarg = argv[d->optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Check whether it might be a long option. */
|
||||
if (longopts)
|
||||
{
|
||||
if (argv[d->optind][1] == '-')
|
||||
{
|
||||
/* "--foo" is always a long option. The special option
|
||||
"--" was handled above. */
|
||||
d->__nextchar = argv[d->optind] + 2;
|
||||
return process_long_option (argc, argv, optstring, longopts,
|
||||
longind, long_only, d,
|
||||
print_errors, "--");
|
||||
}
|
||||
|
||||
/* If long_only and the ARGV-element has the form "-f",
|
||||
where f is a valid short option, don't consider it an
|
||||
abbreviated form of a long option that starts with f.
|
||||
Otherwise there would be no way to give the -f short
|
||||
option.
|
||||
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an
|
||||
abbreviation of the long option, just like "--fu", and
|
||||
not "-f" with arg "u".
|
||||
|
||||
This distinction seems to be the most useful approach. */
|
||||
if (long_only && (argv[d->optind][2]
|
||||
|| !strchr (optstring, argv[d->optind][1])))
|
||||
{
|
||||
int code;
|
||||
d->__nextchar = argv[d->optind] + 1;
|
||||
code = process_long_option (argc, argv, optstring, longopts,
|
||||
longind, long_only, d,
|
||||
print_errors, "-");
|
||||
if (code != -1)
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
/* It is not a long option. Skip the initial punctuation. */
|
||||
d->__nextchar = argv[d->optind] + 1;
|
||||
}
|
||||
|
||||
/* Look at and handle the next short option-character. */
|
||||
|
||||
{
|
||||
char c = *d->__nextchar++;
|
||||
const char *temp = strchr (optstring, c);
|
||||
|
||||
/* Increment 'optind' when we start to process its last character. */
|
||||
if (*d->__nextchar == '\0')
|
||||
++d->optind;
|
||||
|
||||
if (temp == NULL || c == ':' || c == ';')
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
|
||||
d->optopt = c;
|
||||
return '?';
|
||||
}
|
||||
|
||||
/* Convenience. Treat POSIX -W foo same as long option --foo */
|
||||
if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL)
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*d->__nextchar != '\0')
|
||||
d->optarg = d->__nextchar;
|
||||
else if (d->optind == argc)
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr,
|
||||
_("%s: option requires an argument -- '%c'\n"),
|
||||
argv[0], c);
|
||||
|
||||
d->optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
return c;
|
||||
}
|
||||
else
|
||||
d->optarg = argv[d->optind];
|
||||
|
||||
d->__nextchar = d->optarg;
|
||||
d->optarg = NULL;
|
||||
return process_long_option (argc, argv, optstring, longopts, longind,
|
||||
0 /* long_only */, d, print_errors, "-W ");
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*d->__nextchar != '\0')
|
||||
{
|
||||
d->optarg = d->__nextchar;
|
||||
d->optind++;
|
||||
}
|
||||
else
|
||||
d->optarg = NULL;
|
||||
d->__nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*d->__nextchar != '\0')
|
||||
{
|
||||
d->optarg = d->__nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
d->optind++;
|
||||
}
|
||||
else if (d->optind == argc)
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr,
|
||||
_("%s: option requires an argument -- '%c'\n"),
|
||||
argv[0], c);
|
||||
|
||||
d->optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented 'optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
d->optarg = argv[d->optind++];
|
||||
d->__nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_getopt_internal (int argc, char **argv, const char *optstring,
|
||||
const struct option *longopts, int *longind, int long_only,
|
||||
int posixly_correct)
|
||||
{
|
||||
int result;
|
||||
|
||||
getopt_data.optind = optind;
|
||||
getopt_data.opterr = opterr;
|
||||
|
||||
result = _getopt_internal_r (argc, argv, optstring, longopts,
|
||||
longind, long_only, &getopt_data,
|
||||
posixly_correct);
|
||||
|
||||
optind = getopt_data.optind;
|
||||
optarg = getopt_data.optarg;
|
||||
optopt = getopt_data.optopt;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt.
|
||||
Standalone applications just get a POSIX-compliant getopt.
|
||||
POSIX and LSB both require these functions to take 'char *const *argv'
|
||||
even though this is incorrect (because of the permutation). */
|
||||
#define GETOPT_ENTRY(NAME, POSIXLY_CORRECT) \
|
||||
int \
|
||||
NAME (int argc, char *const *argv, const char *optstring) \
|
||||
{ \
|
||||
return _getopt_internal (argc, (char **)argv, optstring, \
|
||||
0, 0, 0, POSIXLY_CORRECT); \
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
GETOPT_ENTRY(getopt, 0)
|
||||
GETOPT_ENTRY(__posix_getopt, 1)
|
||||
#else
|
||||
GETOPT_ENTRY(getopt, 1)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of 'getopt'. */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
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 '?':
|
||||
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,61 +0,0 @@
|
|||
/* Declarations for getopt.
|
||||
Copyright (C) 1989-2023 Free Software Foundation, Inc.
|
||||
This file is part of gnulib.
|
||||
Unlike most of the getopt implementation, it is NOT shared
|
||||
with the GNU C Library, which supplies a different version of
|
||||
this file.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_GETOPT_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. We must
|
||||
also inform the replacement unistd.h to not recursively use
|
||||
<getopt.h>; our definitions will be present soon enough. */
|
||||
#if @HAVE_GETOPT_H@
|
||||
# define _GL_SYSTEM_GETOPT
|
||||
# @INCLUDE_NEXT@ @NEXT_GETOPT_H@
|
||||
# undef _GL_SYSTEM_GETOPT
|
||||
#endif
|
||||
|
||||
#define _@GUARD_PREFIX@_GETOPT_H 1
|
||||
|
||||
/* Standalone applications should #define __GETOPT_PREFIX to an
|
||||
identifier that prefixes the external functions and variables
|
||||
defined in getopt-core.h and getopt-ext.h. When this happens,
|
||||
include the headers that might declare getopt so that they will not
|
||||
cause confusion if included after this file (if the system had
|
||||
<getopt.h>, we have already included it). */
|
||||
#if defined __GETOPT_PREFIX
|
||||
# if !@HAVE_GETOPT_H@
|
||||
# define __need_system_stdlib_h
|
||||
# include <stdlib.h>
|
||||
# undef __need_system_stdlib_h
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The definition of _GL_ARG_NONNULL is copied here. */
|
||||
|
||||
#include <getopt-cdefs.h>
|
||||
#include <getopt-pfx-core.h>
|
||||
#include <getopt-pfx-ext.h>
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_GETOPT_H */
|
|
@ -1,159 +0,0 @@
|
|||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987-2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library and is also part of gnulib.
|
||||
Patches to this file should be submitted to both projects.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _LIBC
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
#include "getopt_int.h"
|
||||
|
||||
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, d, 0);
|
||||
}
|
||||
|
||||
/* 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, d, 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.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 const 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 */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue