commit c9ef7ad16d1b293e65175e47015633e3cbfce49f Author: openKylinBot Date: Fri May 13 23:02:57 2022 +0800 Import Upstream version 2.9.9 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..afc4e6b --- /dev/null +++ b/AUTHORS @@ -0,0 +1,48 @@ +Current Maintainer +------------------ + +Nikolaus Rath + + +Past Maintainers +---------------- + +Miklos Szeredi (until 12/2015) + + +Contributors +------------ + +CUSE has been written by Tejun Heo . Furthermore, the +following people have contributed patches (autogenerated list): + +Alexander +Anatol Pomozov +Bill Zissimopoulos +Carl Edquist +Csaba Henk +Dalvik Khertel +Daniel Thau +David McNab +Emmanuel Dreyfus +Fabrice Bauzac +Hendrik Brueckner +Jann Horn +John Muir +Laszlo Papp +Madan Valluri +Mark Glines +Max Krasnyansky +Michael Grigoriev +Miklos Szeredi +Miklos Szeredi +mkmm@gmx-topmail.de +Natanael Copa +Nikolaus Rath +Olivier Blin +Ratna_Bolla@dell.com +Reuben Hawkins +Roland Bauerschmidt +Rostislav Skudnov +Sebastian Pipping +therealneworld@gmail.com diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This 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. + + This 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..13a369f --- /dev/null +++ b/ChangeLog @@ -0,0 +1,3573 @@ +FUSE 2.9.9 (2019-01-04) +======================= + +* Added OpenAFS to whitelist (so users can now mount FUSE filesystems + on mountpoints within OpenAFS filesystems). +* Added a test of `seekdir` to test_syscalls. +* Fixed `readdir` bug when non-zero offsets are given to filler and the + filesystem client, after reading a whole directory, re-reads it from a + non-zero offset e. g. by calling `seekdir` followed by `readdir`. + +FUSE 2.9.8 (2018-07-24) +======================= + +* SECURITY UPDATE: In previous versions of libfuse it was possible to + for unprivileged users to specify the `allow_other` option even when + this was forbidden in `/etc/fuse.conf`. The vulnerability is + present only on systems where SELinux is active (including in + permissive mode). +* libfuse no longer segfaults when fuse_interrupted() is called outside + the event loop. +* The fusermount binary has been hardened in several ways to reduce + potential attack surface. Most importantly, mountpoints and mount + options must now match a hard-coded whitelist. It is expected that + this whitelist covers all regular use-cases. +* Fixed rename deadlock on FreeBSD. + +FUSE 2.9.7 (2016-06-20) +======================= + +* Added SELinux support. +* Fixed race-condition when session is terminated right after starting + a FUSE file system. + +FUSE 2.9.6 (2016-04-23) +======================= + +* Tarball now includes documentation. +* Shared-object version has now been bumped correctly. + +FUSE 2.9.5 (2016-01-14) +======================= + +* New maintainer: Nikolaus Rath . Many thanks to + Miklos Szeredi for bringing FUSE to where it is + now! + +* fix warning in mount.c:receive_fd(). Reported by Albert Berger + +* fix possible memory leak. Reported by Jose R. Guzman + +FUSE 2.9.4 (2015-05-22) +======================= + +* fix exec environment for mount and umount. Found by Tavis Ormandy + (CVE-2015-3202). + +* fix fuse_remove_signal_handlers() to properly restore the default + signal handler. Reported by: Chris Johnson + +* highlevel API: fix directory file handle passed to ioctl() method. + Reported by Eric Biggers + +* libfuse: document deadlock avoidance for fuse_notify_inval_entry() + and fuse_notify_delete() + +* fusermount, libfuse: send value as unsigned in "user_id=" and + "group_id=" options. Uids/gids larger than 2147483647 would result + in EINVAL when mounting the filesystem. This also needs a fix in + the kernel. + +* Initilaize stat buffer passed to ->getattr() and ->fgetattr() to + zero in all cases. Reported by Daniel Iwan + +* libfuse: Add missing includes. This allows compiling fuse with + musl. Patch by Daniel Thau + + +Older Versions (before 2013-01-01) +================================== + + +2013-06-20 Miklos Szeredi + + * libfuse: fix multiple close of device fd. Reported by Dan + Greenfield + +2013-03-19 Miklos Szeredi + + * libfuse: fix thread cancel race. Exiting a worker my race with + cancelling that same worker. This caused a segmenation + fault. Reported and tested by Anatol Pomozov + +2013-02-04 Miklos Szeredi + + * libfuse: fix crash in unlock_path(). Patch by Ratna Manoj + + * libfuse: fix the 'remember' option. The lru list was not + initialized for the "/" path. This resulted in remove_node_lru() + crashing on LOOKUP-DOTDOT. Patch by Madan Valluri + + * libfuse: configure: detect new util-linux + + * libfuse: Use AC_CONFIG_HEADERS instead of AM_CONFIG_HEADER. + Patch by Anatol Pomozov + + * libfuse: rename ./configure.in to ./configure.ac. Patch by + Anatol Pomozov + +2012-10-01 Miklos Szeredi + + * Released 2.9.2 + +2012-10-01 Miklos Szeredi + + * Fix deadlock in libfuse. Running "svn update" on a fuse + filesystem could deadlock because of a bug in the way the paths + are locked. Reported by Kazuaki Anami + +2012-08-23 Miklos Szeredi + + * Fix missing config.h in buffer.c. Reported by Matthew Gabeler-Lee + +2012-08-14 Miklos Szeredi + + * Not unhashing the name in forget (commit on 2011-12-09) broke + the forget logic in a subtle way, resulting in "fuse internal + error: node NNN not found" and causing the filesystem daemon to + abort. Fix by incrementing the node refcount if nlookup goes from + zero to one. Reported by Kyle Lippincott + +2012-08-13 Miklos Szeredi + + * Fix linking against GNU libiconv. Patch by Natanael Copa + +2012-07-19 Miklos Szeredi + + * Released 2.9.1 + +2012-07-19 Miklos Szeredi + + * Fix crash caused by freeing a stack address. Reported by Itay + Perl + +2012-07-04 Miklos Szeredi + + * Fix install of mount.fuse from out-of-tree build. Patch by + Olivier Blin + + * Fix build with automake >= 1.12.1. Patch by Olivier Blin + +2012-04-24 Miklos Szeredi + + * Add fallocate operation. Only works on linux kernels 3.5 or + later. Patch by Anatol Pomozov + +2012-05-16 Miklos Szeredi + + * Linking to a library that uses threads requires the application + to be linked with -pthreads otherwise some pthread functions will + be linked to stubs in glibc. So move -pthread from Libs.private + to Libs in fuse.pc. Reported by Werner Fink + + * Fix the compile command in the examples. Reported by Luciano + Dalle Ore + +2012-04-20 Miklos Szeredi + + * Released 2.9.0 + +2012-04-20 Miklos Szeredi + + * Add missing fuse_fs_flock to fuse_versionscript + +2012-04-10 Miklos Szeredi + + * Check protocol version before sending notifications and return + -ENOSYS if a particular notification is not supported. + + * Add 'flag_utime_omit_ok' flag to fuse_operations. If the + filesystem sets this flag then ->utimens() will receive UTIME_OMIT + and UTIME_NOW values as specified in utimensat(2). + +2012-01-27 Miklos Szeredi + + * Interpret octal escape codes in options. Requested by Jan + Engelhardt + +2012-01-26 Miklos Szeredi + + * Add man pages for fusermount, mount.fuse and ulockmgr_server. + Lifted from the Debian package. The man pages were written by + Daniel Baumann and Bastien Roucaries + +2012-01-13 Miklos Szeredi + + * Disable symbol versions on MacOSX. Patch by Anatol Pomozov + +2012-01-02 Miklos Szeredi + + * Remove unnecessary mutex unlock at the end of multithreaded + event loop. + +2011-12-09 Miklos Szeredi + + * Fix hang in wait_on_path(). Reported by Ville Silventoinen + + * Don't unhash name in FORGET. This resulted in ENOENT being + returned for unlinked but still open files if the kernel sent a + FORGET request for the parent directory. + + * Free request in fuse_reply_data(). + +2011-12-08 Miklos Szeredi + + * Fix build if FUSE_NODE_SLAB is not defined. Patch by Emmanuel + Dreyfus + + * Check for availability of utimensat() function. Patch by + Emmanuel Dreyfus + +2011-12-07 Miklos Szeredi + + * Add fuse_lowlevel_notify_delete() which tells the kernel that a + file or directory is deleted. Patch by John Muir + +2011-12-06 Miklos Szeredi + + * Update retrieve_reply() method + +2011-12-05 Miklos Szeredi + + * Low level API: lock argument of fuse_reply_lock should have a + 'const' qualifier. Reported by Shachar Sharon + + * Add support for ioctl on directories. Reported by Antonio SJ + Musumeci + +2011-10-13 Miklos Szeredi + + * Reply to request with ENOMEM in case of failure to allocate + request structure. Otherwise the task issuing the request will + just freeze up until the filesystem daemon is killed. Reported by + Stephan Kulow + +2011-09-23 Miklos Szeredi + + * Replace daemon() function with fork(). Patch by Anatol Pomozov + +2011-08-26 Miklos Szeredi + + * If configured with --disable-mtab then don't call mount(8) from + libfuse to update the mtab. Reported by: James Sierp + +2011-08-24 Miklos Szeredi + + * Use LRU list for cleaning up the cache if the "remember=T" + option was given. Patch by therealneworld@gmail.com + +2011-07-06 Miklos Szeredi + + * Add ->flock() operation to low and high level interfaces. This + fixes problems with emulating flock() with POSIX locking. + Reported by Sebastian Pipping. As with lock/setlk/getlk most + filesystems don't need to implement this, as the kernel takes care + of file locking. The only reason to implement locking operations + is for network filesystems which want file locking to work between + clients. + +2011-07-02 Sebastian Pipping + + * Make xmp_utimens of examples "fusexmp" and "fusexmp_fh" + not follow symlinks as other layers do that already. + +2011-06-02 Miklos Szeredi + + * Add "remember" option. This works similar to "noforget" except + that eventually the node will be allowed to expire from the cache. + Patch by therealneworld@gmail.com + +2011-05-27 Miklos Szeredi + + * Check if splice/vmsplice are supported + +2011-05-26 Miklos Szeredi + + * Remove -lrt -ldl from fuse.pc for dynamic linking since + libfuse.so is already linked with these libraries. Reported by: + Nikolaus Rath + +2011-05-20 Miklos Szeredi + + * Cleaner build output. Patch by Reuben Hawkins + +2011-05-19 Miklos Szeredi + + * Disable splice by default, add "splice_read", "splice_write" and + "splice_move" options. Keep the "no_splice_*" variants, which can + disable splice even if the filesystem explicitly enables it. + +2011-04-15 Max Krasnyansky + * Added support for "auto_unmount" option which unmounts the + filesystem automatically on process exit (or crash). + +2011-03-30 Miklos Szeredi + + * Patches by Laszlo Papp fixing various issues found by the + Coverity checker + +2011-03-11 Miklos Szeredi + + * In case of failure to add to /etc/mtab don't umount. Reported + by Marc Deslauriers + +2011-02-02 Miklos Szeredi + + * libfuse: In fuse_session_loop_mt() don't pause when exiting the + worker threads. The pause() was added in 2.2.1 to prevent + segfault on pthread_cancel() on an exited, detached thread. Now + worker threads are not detached and pthread_cancel() should work + fine even after the thread exited. Reported by Boris Protopopov + +2011-01-31 Miklos Szeredi + + * fusermount: chdir to / before performing mount/umount + + * fusermount: only allow mount and umount if util-linux supports + --no-canonicalize + +2010-12-16 Miklos Szeredi + + * Highlevel lib: allow hash tables to shrink + + * Highlevel lib: add slab allocation for node cache. This will + allow the memory used by the filesystem to grow and shrink + depending on how many inodes are currently cached. + +2010-12-13 Miklos Szeredi + + * Highlevel lib: use dynamically resized hash table for looking up + by name and node ID. + +2010-12-07 Miklos Szeredi + + * Allow batching of forget requests. This allows forget requests + to be processed faster and doesn't require a modification to fuse + filesystems. Reported by Terje Malmedal + + * Add ->forget_multi() operation to the lowlevel API. The + filesystem may implement this to process multiple forget requests + in one call + + * Fix the ambiguity of ioctl ABI on the kernel/userspace boundary + for 32bit vs. 64bit userspace + +2010-11-10 Miklos Szeredi + + * Add new write_buf() method to the highlevel API. Similarly to + the lowlevel write_buf() method, this allows implementing zero + copy writes. + + * Add a new read_buf() method to the highlevel API. This allows + returning a generic buffer from the read method, which in turn + allows zero copy reads. + + * In fusexmp_fh implement the ->read_buf() and ->write_buf() + methods. Leave the ->read() and ->write() implementations for + reference, even though they are not necessary. + +2010-11-08 Miklos Szeredi + + * Fix check for read-only fs in mtab update + + * Open /dev/null for write instead of read for redirecting stdout + and stderr + + * If umount(8) supports --fake and --no-canonicalize (util-linux-ng + version 2.18 or later), and umount(2) supports the + UMOUNT_NOFOLLOW flag (linux kernel version 2.6.35 or later) then, + "fusermount -u" will call the umount(2) system call and use + "umount --fake ..." to update /etc/mtab + + * Added --disable-legacy-umount option to configure. This + disables the runtime checking of umount(8) version. When built + with this option then "fusermount -u" will fail if umount(8) + doesn't support the --fake and --no-canonicalize options. + + * Fix fuse_buf_copy() if already at the end of the buffers + + * Add new ->write_buf() method to low level interface. This + allows passig a generic buffer, either containing a memory buffer + or a file descriptor. This allows implementing zero copy writes. + + * Add fuse_session_receive_buf() and fuse_session_process_buf() + which may be used in event loop implementations to replace + fuse_chan_recv() and fuse_session_process() respectively. + + * Remove unnecessary restoring of current working directory in + "fusermount -u" + + * Add ctx->pid to debug output + + * Fix st_nlink value in high level lib if file is unlinked but + still open + + * libfuse: add store request. Request data to be stored in the + kernel buffers for a given inode. + + * libfuse: add retrieve request. Retrieve data stored in the + kernel buffers for a given inode. + +2010-10-14 Miklos Szeredi + + * Use LTLIBICONV when linking libfuse. This fixes building against + uclibc + libiconv. Patch by Natanael Copa + +2010-10-05 Miklos Szeredi + + * Add missing argument check in ulockmgr.c to prevent calling + ulockmgr_server with illegal arguments. This would cause an ever + growing list of ulockmgr_server processes with an endless list of + open files which finally exceeds the open file handle limit. + Patch by Markus Ammer + +2010-09-28 Miklos Szeredi + + * Fix ambiguous symbol version for fuse_chan_new. + fuse_versionscript included fuse_chan_new in both FUSE_2.4 and + FUSE_2.6. Remove the FUSE_2.4, which is invalid. + +2010-09-28 Miklos Szeredi + + * Fix option escaping for fusermount. If the "fsname=" option + contained a comma then the option parser in fusermount was + confused (Novell bugzilla #641480). Fix by escaping commas when + passing them over to fusermount. Reported by Jan Engelhardt + +2010-08-27 Miklos Szeredi + + * Add NetBSD support. Patch from Emmanuel Dreyfus + +2010-07-12 Miklos Szeredi + + * libfuse: add buffer interface. Add a generic buffer interface + for use with I/O. Buffer vectors are supplied and each buffer in + the vector may be a memory pointer or a file descriptor. + + * The fuse_reply_fd() interface is converted to using buffers. + +2010-06-23 Miklos Szeredi + + * Make the number of max background requests and congestion + threshold tunable. New options are "max_background" and + "congestion_threshold". Only effective on linux kernel versions + 2.6.32 or greater. Patch by Csaba Henk + +2010-06-17 Miklos Szeredi + + * Add fuse_reply_fd() reply function to the low level interface. + On linux version 2.6.35 or greater this will use splice() to move + data directly from a file descriptor to the fuse device without + needing to go though a userspace buffer. With the + FUSE_REPLY_FD_MOVE flag the kernel will attempt to move the data + directly into the filesystem's cache. On earlier kernels it will + fall back to an intermediate buffer. The options + "no_splice_write" and "no_splice_move" can be used to disable + splicing and moving respectively. + +2010-06-15 Miklos Szeredi + + * Fix out-of-source build. Patch by Jörg Faschingbauer + + * Add a "nopath" option and flag, indicating that path argument + need not be calculated for the following operations: read, write, + flush, release, fsync, readdir, releasedir, fsyncdir, ftruncate, + fgetattr, lock, ioctl and poll. + +2010-05-10 Miklos Szeredi + + * Remove "chmod root" from install of fusermount. Reported by + Lucas C. Villa Real + +2010-04-26 Miklos Szeredi + + * Released 2.8.4 + +2010-04-26 Miklos Szeredi + + * Fix checking for symlinks in umount from /tmp. Reported by Al + Viro + + * Fix umounting if /tmp is a symlink. Reported by Franco Broi + +2010-02-18 Miklos Szeredi + + * Fix definition of FUSE_OPT_END for C++. Reported by Tim + Bruylants + +2010-02-03 Miklos Szeredi + + * Fix stack alignment for clone() + +2010-02-01 Miklos Szeredi + + * Released 2.8.3 + +2010-02-01 Miklos Szeredi + + * Using "--no-canonicalize" with umount(8) conflicts with the race + fix, sinceit assumes the supplied path is absolute, while the race + fix relies on the path being relative to the current directory. + Reported by Tom Rindborg + +2010-01-26 Miklos Szeredi + + * Released 2.8.2 + +2010-01-21 Miklos Szeredi + + * Fix race if two "fusermount -u" instances are run in parallel. + Reported by Dan Rosenberg + + * Make sure that the path to be unmounted doesn't refer to a + symlink + +2010-01-14 Miklos Szeredi + + * Fix compile error on FreeBSD. Patch by Jay Sullivan + +2009-12-17 Miklos Szeredi + + * Use '--no-canonicalize' option of mount(8) (available in + util-linux-ng version 2.17 or greater) to avoid calling + readling(2) on the newly mounted filesystem before the mount + procedure is finished. This has caused a deadlock if "audit" was + enabled in the kernel. Also use '--no-canonicalize' for umount to + avoid touching the mounted filesystem. + +2009-09-11 Miklos Szeredi + + * Released 2.8.1 + +2009-08-25 Miklos Szeredi + + * Fix missing versioned symbol fuse_get_context@FUSE_2.2 + +2009-08-18 Miklos Szeredi + + * Released 2.8.0 + +2009-08-18 Miklos Szeredi + + * Add missing fuse_session_data to versionscript + + * Make sure all global symbols are prefixed with "fuse_" or "cuse_" + +2009-07-16 Miklos Szeredi + + * Clarify how the protocol version should be negotiated between + kernel and userspace. Notably libfuse didn't correctly handle the + case when the supported major versions didn't match + + * Add missing pthread link for libulockmgr. Patch by Petr Salinger + +2009-07-02 Miklos Szeredi + + * The context is extended with a 'umask' field. The umask is sent + for mknod, mkdir and create requests by linux kernel version + 2.6.31 or later, otherwise the umask is set to zero. Also + introduce a new feature flag: FUSE_CAP_DONT_MASK. If the kernel + supports this feature, then this flag will be set in conn->capable + in the ->init() method. If the filesystem sets this flag in in + conn->want, then the create modes will not be masked. + + * Add low level interfaces for lookup cache and attribute + invalidation. This feature is available in linux kernels 2.6.31 + or later. Patch by John Muir + + * Kernel interface version is now 7.12 + + * fusermount: Do not silently ignore command line arguments. + Patch by Sebastian Harl + +2009-06-19 Miklos Szeredi + + * Released 2.8.0-pre3 + +2009-06-19 Miklos Szeredi + + * Add fuse_getgroups (high level lib) and fuse_req_getgroups (low + level lib) functions to query the supplementary group IDs for the + current request. Currently this is implemented on Linux by + reading from the /proc filesystem. + +2009-06-18 Miklos Szeredi + + * Add "noforget" option to high level lib to prevent ESTALE errors + on NFS exported filesystems. This result in paths being cached + forever, resulting in ever growing memory usage. Use with care. + + * Add "no_remote_lock" option to disable remote file locking even + if the filesystem implements it. With this option locking + primitives (flock, lockf, fcntl(F_SETLK)) will still work, but + will ignore remotely locked files. + + * CUSE patches from Tejun Heo: + + * Unrestricted ioctl support left some debris. Clean them up: + o No reason to pass around pointer to flags. Pass flags directly. + o Clean up comment and prototype parameter names. + o fuse_lib_ioctl() didn't reply when get_path() failed. Fix it. + o Remove unused variables {in|out}_iov from fuse_lib_ioctl(). + + * Add fuse_reply_ioctl_iov() + + * Move fuse_session, fuse_req and fuse_ll definitions to fuse_i.h + and make send_reply_iov() and fuse_setup_common() global (also in + fuse_i.h). These will be used by CUSE support. + + * Restructure fuse_ll_process() + + * Implement libfuse side of CUSE support. CUSE uses subset of FUSE + operations as dir operations don't make sense for CUSE where one + instance implements single character device. + + CUSE support comes with its own cuse_lowevel_ops and related + initialization and helper functions. Except for initialization, it + usage is basically identical to FUSE. + + This patch also adds example/cusexmp.c which can create a character + device with name and device number specified on command line. The + created device itself is pretty boring. It's a bit bucket supporting + read, write and access via ioctl. + +2009-06-16 Miklos Szeredi + + * Add missing fuse_reply_bmap to versionscript. Debian + Bug#531329. Reported by Goswin Brederlow + +2009-05-27 Miklos Szeredi + + * Don't call forget_node() if the lookup was negative and write() + for the reply returned ENOENT. Reported by John Haxby + +2009-05-25 Miklos Szeredi + + * Add FUSE_CAP_EXPORT_SUPPORT to fuse_common.h + +2009-05-08 Miklos Szeredi + + * Fix missing newlines in some printfs + + * Fix 'make install-strip'. Reported by Dominick Layfield + +2009-01-05 Miklos Szeredi + + * Released 2.8.0-pre2 + +2008-12-08 Miklos Szeredi + + * Implement poll support. Patch by Tejun Heo + + * Add missing setattr flags to . + + * Only pass valid flags to ->setattr(). + +2008-12-05 Miklos Szeredi + + * Implement ioctl support. On high level interface only + "restricted" ioctls are supported (which are defined with the + _IO(), _IOR(), _IOW() or _IOWR() macros). Unrestricted ioctls + will only be allwed to CUSE (Character Device in Userspace) + servers. Patch by Tejun Heo + +2008-11-28 Miklos Szeredi + + * If open sets fi->nonseekable, libfuse will tell the kernel that + the file is not seekable. Patch by Tejun Heo + +2008-11-19 Miklos Szeredi + + * lowlevel lib: fix deadlock if fuse_reply_* is called from the + interrupt handling function. Reported by Tero Marttila + +2008-10-16 Miklos Szeredi + + * Allow commas in options to be escaped with a backslash + + * Add new function: fuse_opt_add_opt_escaped() + + * Add missing fuse_reply_bmap() to the version script + +2008-10-14 Miklos Szeredi + + * Pass current file flags to read and write operations + +2008-07-24 Miklos Szeredi + + * Clean up debug output in highlevel lib + +2008-07-10 Miklos Szeredi + + * Released 2.8.0-pre1 + +2008-06-27 Miklos Szeredi + + * Fix handling of (no)suid and (no)dev options if filesystem is + mounted from /etc/fstab or via mount(8). Reported by Jan Ondrej. + + * Skip calling mount(8) if /etc/mtab doesn't exist or if it's on a + read-only filesystem. This works around issues with certain mount + implementations. Reported by Szabolcs Szakacsits. + +2008-06-16 Miklos Szeredi + + * Remove fuse kernel module sources. Linux 2.6.27 will support + NFS exporting. + +2008-06-10 Miklos Szeredi + + * Fix theoretical infinite loops in libfuse. Reported by Szabolcs + Szakacsits + + * Fix missing include for PATH_MAX. Reported by + Szabolcs Szakacsits + +2008-05-23 Miklos Szeredi + + * Fix mounting over symlink. Reported by Szabolcs Szakacsits + +2008-05-09 Miklos Szeredi + + * Don't allow bigger than 4kB writes by default on 2.6.26 and + later kernels, so that filesystems not expecting this are not + broken on a kernel upgrade. Provide a 'big_writes' mount option + to enable this feature. In future API revisions this may become + the default. + +2008-04-09 Miklos Szeredi + + * Update warning message for missing newline at end of fuse.conf + + * Update debug message for successful operation to not include the + string "error:" + +2008-04-08 Miklos Szeredi + + * Update error message for missing mountpoint parameter. Reported + by Allen Pulsifer + +2008-04-04 Miklos Szeredi + + * Print library version information to debug output + + * Highlevel lib: don't limit paths to 4095 characters + +2008-03-25 Miklos Szeredi + + * Fix memory leaks on mount. Patch by Szabolcs Szakacsits + +2008-03-19 Miklos Szeredi + + * Fix missing pthread_mutex_destroy in error path of + fuse_lib_opendir(). Patch by Szabolcs Szakacsits + +2008-03-07 Miklos Szeredi + + * Add queuing on contention to per-node lock algorithm, to avoid + starvation. + + * Only enable cancelation when reading a request, otherwise + cancellation could happen with a mutex held, which could hang the + process on umount + +2008-02-08 Miklos Szeredi + + * Block SIGCHLD when executing mount and umount + + * fusexmp_fh: avoid unnecessary seeking in readdir + + * Update kernel interface to 7.9: + + * Support receiving file handle from kernel in GETATTR request + + * Allow operations with a NULL path argument, if the filesystem + supports it + + * Add support atomic open(O_TRUNC) + + * Support the st_blksize field in struct stat + + * If the "FUSE_THREAD_STACK" environment is set, initialize the + stack size of threads by this value. Patch by Florin Malita + + * Add per-node locking, instead of a global tree lock to protect + the path from changing during operations. Original patch by + Rodrigo Castro + +2008-02-03 Csaba Henk + + * lib/mount_bsd.c: + - string formatting fixes + - exit if mounting has failed + (in FreeBSD a mount failure is not critical per se, as the daemon + still could be mounted externally, but waiting for such an event + is more confusing than fruitful) + - ditch the kvm(8) stuff and simply use forced unmount which just + won't block + - prettify option specifications + - add "-onosync_unmount" kernel option + +2008-01-07 Csaba Henk + + * lib/mount_bsd.c: + - refine device closing in a race-free way + - add support for "-osubtype" on FreeBSD + + * makeconf.sh: make it work under FreeBSD + +2008-01-03 Csaba Henk + + * lib/mount_bsd.c: close device before unmount + (cf. lib/mount.c rev. 1.43) and fix some warnings + +2007-12-23 Miklos Szeredi + + * Fix './configure --disable-static'. Patch from Ismail Dönmez + +2007-12-17 Miklos Szeredi + + * Released 2.7.2 + +2007-12-12 Miklos Szeredi + + * Fix kernel module compile for 2.6.24 + + * Invalidate attributes of parent directory after create(), since + the modification time changes. Invalidate attributes on rename, + since some filesystems may update st_ctime. Reported by Szabolcs + Szakacsits + + * Fix NFS exporting to handle 64bit node IDs + + * Disable old symbol versions if __UCLIBC__ is defined. If a + symbol in a library has multiple versions, the runtime linker in + uClibc seems to randomly choose between them. + + * Remove erroneous 'fuse_opt_insert_arg@FUSE_2_5' from + fuse_version_script. fuse_opt_free_args() was added in fuse-2.6. + + * Close fuse device file descriptor before calling umount(), + preventing a deadlock when umount is synchronous. Reported by + Szabolcs Szakacsits + +2007-11-12 Miklos Szeredi + + * 'fusermount -u' did not umount the filesystem if /etc/mtab was a + symlink. This bug was introduced in 2.7.1 by "Don't call + /bin/[u]mount if /etc/mtab is a symlink". Found by robertsong. + +2007-10-16 Miklos Szeredi + + * Released 2.7.1 + +2007-10-16 Miklos Szeredi + + * Clarify licence version to be "LGPLv2" for the library + + * kernel fixes: + + * After mount set nlink attribute for the root inode to 1 + + * Fix wake up of task waiting for a reserved request + + * Fix allowing setattr, listxattr and statfs for other users + +2007-09-18 Miklos Szeredi + + * Add missing context initialization in fuse_fs_chmod(). Bug + found by "iohead" + + * Fix kernel module compilation for 2.6.23. Based on patch by + Marian Marinov + +2007-09-04 Philippe Elie + + * lib/fuse_lowlevel.c: fix a fuse_req leak in do_forget() + +2007-07-31 Miklos Szeredi + + * Work around hotplug issue, that it calls filesystem with file + descriptors 0, 1 and 2 not open. Tracked down by Leif Johnson + +2007-07-25 Miklos Szeredi + + * Don't call /bin/[u]mount if /etc/mtab is a symlink. Reported by + Tomas M + + * Also don't touch /etc/mtab if it is within the mounted + filesystem. Suggested by Jeffrey Law + +2007-07-12 Miklos Szeredi + + * Reset args->argc in fuse_opt_free_args(). Patch by Lucas + C. Villa Real + +2007-07-02 Miklos Szeredi + + * Released 2.7.0 + +2007-07-02 Miklos Szeredi + + * Accept a NULL "op" for fuse_main(), etc. This is useful if + filesystem is only invoking fuse to print a help message, or + version. Fixes RedHat bugzilla #217343 + +2007-06-22 Miklos Szeredi + + * lib: fix locking when loading a filesystem module + +2007-06-21 Miklos Szeredi + + * Add fs subtype support to mount.fuse + +2007-06-20 Miklos Szeredi + + * Add fs subtype support to libfuse and fusermount + +2007-06-19 Miklos Szeredi + + * kernel: sync with mainline (2.6.22) + +2007-06-18 Miklos Szeredi + + * Send debug output to stderr instead of stdout. Patch by Jan + Engelhardt + +2007-06-03 Miklos Szeredi + + * libulockmgr: Work around a kernel bug in recv(), causing it to + sometimes return zero even if data was available on the socket. + +2007-05-29 Miklos Szeredi + + * lib: optimization: store parent pointer in node instead of + parent id + +2007-05-25 Miklos Szeredi + + * lib: don't create new thread for each FORGET request. FORGET + messages sometimes caused so many threads to be created, that + process virtual memory space ran out. Reported by Chris AtLee + +2007-05-24 Miklos Szeredi + + * lib: fix memory leak on thread creation failure in multithreaded + event loop. Found by Chris AtLee + +2007-05-23 Miklos Szeredi + + * lowlevel lib: add fuse_reply_iov function, which is similar to + fuse_reply_buf, but accepts a vector of buffers. Patch by Roger + Willcocks + +2007-05-21 Miklos Szeredi + + * Fix Oops or error if a regular file is created with mknod(2) on + a fuse filesystem. Kernels 2.6.18 onward are affected. Thanks to + J. Cameijo Cerdeira for the report + +2007-05-11 Csaba Henk + + * libfuse: fix return value of fuse_loop()/fuse_loop_mt(). + Error reported by Csaba Henk, fix by Miklos Szeredi + + * libfuse: fix unlock in flush + + * libfuse: do unlocking on RELEASE+FLUSH + +2007-05-03 Miklos Szeredi + + * Released 2.7.0-rc1 + +2007-05-02 Miklos Szeredi + + * kernel: sync with mainline: + + * Use invalidate_mapping_pages() if available + + * Fix BUG when invalid file type is supplied in mount. Patch by + Timo Savola + +2007-04-27 Miklos Szeredi + + * libfuse: call umount(8) directly instead of fusermount if + possible + + * Clean up init script, make it LSB compliant + +2007-04-26 Miklos Szeredi + + * In multithreaded loop, use a semaphore instead of SIGHUP to wake + up the main thread on umount. This is more elegant, and works + even if signals are blocked. + +2007-04-25 Miklos Szeredi + + * Improve mounting support in libfuse: + - check non-empty mountpoint + - only fall back to fusermount when necessary + +2007-04-23 Miklos Szeredi + + * Don't chdir to "/" in foreground mode, it causes more trouble + than it's worth + +2007-04-18 Miklos Szeredi + + * Replace utils/mount.fuse "sh" script with a "C" program + +2007-04-15 Miklos Szeredi + + * Add -lulockmgr to compilation comment in fusexmp_fh.c + +2007-04-05 Miklos Szeredi + + * Check for iconv. Patch by Csaba Henk + + * Add direct umounting + + * Use "fusectl" as the device for the fusectl filesystem. Debian + Bug#417945. Reported by Laurent Bonnaud + +2007-04-01 Csaba Henk + + * Fix some FreeBSD related macros. + +2007-03-30 Miklos Szeredi + + * Add support for direct mounting by libfuse. Fall back on + calling fusermount if it doesn't work + +2007-03-14 Miklos Szeredi + + * Released 2.7.0-pre1 + +2007-03-05 Miklos Szeredi + + * Correctly handle O_APPEND in direct IO mode. Reported by Greg + Bruno + + * mount.fuse should use /bin/bash. Debian Bug#413403. Reported + by Thomas Weinbrenner + +2007-02-26 Miklos Szeredi + + * Fix detection of installed fuse in init script. Reported and + fix suggested by Davide Canova + +2007-02-05 Miklos Szeredi + + * Fix 2.6.9 RHEL kernels, which have compatibility mutex.h, but + don't define mutex_destroy(), bummer. Patch from Phil Schwan + +2007-02-04 Miklos Szeredi + + * Compile fuseblk for kernels which don't have an option to turn + off the block layer (CONFIG_BLOCK). Reported by Szakacsits + Szabolcs + +2007-02-03 Miklos Szeredi + + * Add filesystem stacking support to high level API. Filesystem + modules can be built into libfuse or loaded from shared object + (.so) files + + * Add 'subdir' and 'iconv' built in modules + + * lib/fuse.c: Fix locking for the reply code in create and open + +2007-02-02 Miklos Szeredi + + * kernel: make it compile on "strange" kernels which have emulated + mutexes via but no i_mutex. Reported by Tomasz + Mateja + +2007-01-28 Miklos Szeredi + + * kernel: fix BUG in control filesystem if it is umounted and + mounted again, while some fuse filesystems are present. + Bugreport from Florent Mertens + + * kernel: sync with mainline, support 2.6.20 + +2007-01-22 Miklos Szeredi + + * lib/Makefile.am: actually link libfuse against libfuse_libs + +2007-01-19 Miklos Szeredi + + * Build fix for 2.6.16 vanila and 2.6.15 FC5 kernels. Patch from + Ian Abbott + +2007-01-18 Miklos Szeredi + + * Fix abort in fuse_new() compatibility API for opts == NULL case. + Novell bugzilla #233870. Patch from Takashi Iwai. + +2007-01-13 Miklos Szeredi + + * Fix option parsing in mount.fuse. Patch from Jens M. Noedler + +2007-01-02 Miklos Szeredi + + * Fix unaligned access in file desctriptor passing in libfuse, + fusermount and ulockmgr. Debian bug ID: 404904. Reported and + tested by Sebastian Fontius + +2006-12-16 Miklos Szeredi + + * kernel: don't keep unreferenced inodes in the icache. + +2006-12-15 Miklos Szeredi + + * fusermount: Fix detection of fuseblk. Reported by Szakacsits + Szabolcs + + * lib: Fix use after free in fuse_flush(). Reported by Ron + Lindman + +2006-12-10 Miklos Szeredi + + * mount.fuse: add "setuid=USER" option which does a "su - USER" + for the filesystem + + * fusermount: use "/bin/mount -f" to add entry to /etc/mtab, and + "/bin/umount" to remove entry from /etc/mtab. This gets rid of + the ugly code dealing with mtab, as well as a possible race + between fusermount and mount trying to modify /etc/mtab at the + same time + + * Fix "buffer size too small: 4" warning for users of the + fuse_loop_mt_proc() function. + +2006-12-04 Miklos Szeredi + + * Fix warnings with gcc-4.1 on 64bit archs. Report from + Harshavardhana + + * Add extra warning options, and fix resulting warnings + + * Really fix fuse_teardown problem + +2006-12-02 Miklos Szeredi + + * Add -lrt to fuse.pc (if needed) to fix static linking against + libfuse. Reported by Szakacsits Szabolcs + +2006-12-01 Miklos Szeredi + + * Released 2.6.1 + +2006-11-30 Miklos Szeredi + + * Fix API version 21 and 22 compatibility for fuse_teardown. + Reported by Bgs + +2006-11-29 Miklos Szeredi + + * fusermount: Print a more helpful message in case the kernel + doesn't support the 'fuseblk' filesystem type. This has been + biting ntfs-3g users. Reported by Yura Pakhuchiy + + * kernel: fix build problem for "make -C ...". Reported by + Stephen Bryant + +2006-11-19 Miklos Szeredi + + * Fix bug in certain error paths of lookup routines. The request + object was reused for sending FORGET, which is illegal. This bug + could cause an Oops in linux-2.6.18 or in fuse-2.6.0, and might + silently corrupt memory in earlier versions. Report and test + program by Russ Cox + +2006-11-11 Miklos Szeredi + + * Print an error if an incompatible kernel interface version is + detected in INIT. This will only show if filesystem is started + with -d or -f + + * Fix order of fuse_destroy()/fuse_unmount() in error cleanup of + fuse_setup_common(). Reported by Szakacsits Szabolcs + +2006-11-06 Miklos Szeredi + + * Fix recursive locking in fuse_create(). Thanks to Takuya + Ishibashi for the bug report + +2006-10-28 Miklos Szeredi + + * Fix automake problem. Patch from Nix + +2006-10-26 Miklos Szeredi + + * Fix mount.fuse to use /bin/sh instead of /bin/bash, which is not + always available on embedded systems. Patch from Paul Smith + + * Fix util/Makefile.am, so that failure to run update-rc.d or + device creation doesn't cause make to fail. Reported by Paul + Smith + +2006-10-21 Miklos Szeredi + + * Released 2.6.0 + +2006-10-18 Miklos Szeredi + + * fusermount: don't try to create a lock file if /etc/mtab is a + symlink. Report and patch from Alexei Sheplyakov (debian bug + #393693) + +2006-10-17 Miklos Szeredi + + * Minor changes, sync with mainline tree + +2006-10-16 Miklos Szeredi + + * Released 2.6.0-rc3 + +2006-10-15 Miklos Szeredi + + * kernel: cleanups + +2006-10-13 Miklos Szeredi + + * kernel: Fix compilation on patched 2.6.18 (fc6) and 2.6.19. + Report from David Shaw + + * lib: Fix lost error on renaming a file. Report from David Shaw + + * lib: Fix lost error on hiding open files (renaming to + .fuse_hiddenXXXX) + + * kernel: Fix a rare hang on SMP/32bit on heavy filesystem + activity. The cause of the bug was that some calls to + i_size_write() were not protected by a lock, and hence + i_size_seqcount could become corrupted. This caused subsequent + calls to i_size_read() to spin forever. This is a long standing + bug was probably introduced in version 2.2, and thought to be + related to NFS exporting (it's not). It was reported by various + people, but Dana Henriksen has finally helped me to track it down, + so big thanks to him + + * kernel: Protect against truncation of a swapfile + +2006-10-10 Miklos Szeredi + + * kernel: Check for signature of super_operations->umount_begin(). + Ubuntu kernel 2.6.17 seems to use the new signature found in + 2.6.18. Thanks to Florent Mertens for the report + +2006-10-08 Miklos Szeredi + + * Make sure inode numers wrap around at 2^32. This is needed on + dual 64bit/32bit architectures, because 32bit applications using + the non-largefile interface would otherwise break (EOVERFLOW error + would be returned by the stat() system call family) + + * ulockmgr: handle the case, when a locking operation fails + because no more file desctriptors are available in + ulockmgr_server. Also work around a Linux kernel bug (known to + exist for all Linux kernel versions <= 2.6.18) which may cause + sent file descriptors to be lost in the above case + + * ulockmgr: optimize file descriptor use + + * restore needed cpp flags to util/Makefile.am + + * Install udev rules as 99-fuse.rules instead of 60-fuse.rules + + * Minor clean up of udev rules + + * Add a synchronous DESTROY message to kernel interface. This is + invoked from umount, when the final instance of the filesystem is + released. It is only sent for filesystems mounted with the + 'blkdev' option for security reasons. + + * If the DESTROY message is received, call the filesystem's + ->destroy() method. In this case it's not called from session + destruction as it would be otherwise. + +2006-10-01 Miklos Szeredi + + * Released 2.6.0-rc2 + +2006-10-01 Miklos Szeredi + + * Add support for FLUSH+RELEASE operation for FreeBSD. Original + patch by Csaba Henk + + * Add init script to insert fuse module and mount the control + filesystem. The script is installed as /etc/init.d/fuse and on + debian based systems (where update-rc.d is available) symlinks + from /etc/rc*.d/ are also installed. + + * Include '#define FUSE_USE_VERSION=XX' into examples so they + become more self contained. + +2006-09-30 Miklos Szeredi + + * API changes: + + * Move lock_owner from a separate argument into fuse_file_info + + * Add a flag to fuse_file_info indicating (1) a highlevel lock + operation (unlock all) was initiated by a flush, (2) a lowlevel + release operation should perform a flush as well. + + * fusermount: revert modprobe change (2006-08-18) since it + doesn't work reliably with udev + + * Add support for block device backed filesystems. This mode is + selected with the 'blkdev' option, which is privileged. + + * Add support for the bmap (FIBMAP ioctl) operation on block + device backed filesystems. This allows swapon and lilo to work on + such filesystems. + + * kernel changes: + + * Drop support for kernels earlier than 2.6.9. Kernel module from + previous (2.5.x) release can be used with library from this + release + + * In fuse_dentry_revalidate() use dget_parent() instead of + dereferencing d_parent, since there's no protection against parent + changing and going away + + * Protect nlookup from concurrent updates + + * In lookup if a directory alias exists but is unused, + then get rid of it, otherwise return -EBUSY. + + * In mkdir if a directory alias exists, return success, but leave + dentry negative. In reality this could happen if a remote rename + immediately followed the mkdir. + + * Don't BUG in fuse_iget() if multiple retries are needed to get a + good inode. This could happen if several lookups are racing for + the same inode. + +2006-09-29 Miklos Szeredi + + * Fix compilation on 2.6.9. Report from Troy Ayers + +2006-09-27 Miklos Szeredi + + * Fix Oops in fuse_readpages(). Reported by David Shaw + +2006-09-24 Csaba Henk + + * Add support for nanosec times on FreeBSD + + * Fix FreeBSD compatibility issues + +2006-09-23 Miklos Szeredi + + * Fix one more compatibility bug. Thanks to Ricardo Correia + + * Fix utimens compilation with uClibc. Patch from Jamie Guinan + +2006-09-22 Miklos Szeredi + + * Fixed several compatibility bugs in low level interface. + Reported by Ricardo Correia + + * Add workaround for ARM caching bug + +2006-09-16 Miklos Szeredi + + * Rename new utimes() method to more logical utimens() + +2006-09-14 Miklos Szeredi + + * Fuse tried to unlink already unlinked hidden files. Bug + reported by Milan Svoboda + +2006-09-10 Miklos Szeredi + + * Released 2.6.0-rc1 + +2006-09-10 Miklos Szeredi + + * kernel: Fix unlock on close for kernels < 2.6.18 + + * Add ulockmgr library & server. This can be used for handling + file locking requests either directly from libfuse or over a + network, etc. This first version is not optimized and the number + of file descriptors it uses may get out of hand + +2006-09-07 Miklos Szeredi + + * lib: Add interrupt support to high level library, which may be + enabled with the 'intr' mount option. + + * When an operation is interrupted the thread handling that + operation will receive SIGUSR1 (or other signal specified with the + 'intr_signal=N' option). The library installs a no-op signal + handler for this signal, unless there's already a handler + installed. + + * The filesystem may query interrupt status (regardless of 'intr') + with the fuse_interrupted() function. + + * mount.fuse: initialize $HOME if not set. Report from Sven Goldt + +2006-09-03 Miklos Szeredi + + * lib: Multithreaded loop now allows unlimited number of threads. + This is needed for locking operations which may block + indefinitely. Also the kernel now doesn't limit the number of + outstanding requests so the library shouldn't do so either. + +2006-09-01 Miklos Szeredi + + * Fix recursive lock bug in interrupt handling + + * Add utimes() method to highlevel interface, which supports + setting times with nanosecond resolution + +2006-08-18 Miklos Szeredi + + * kernel: fix page leak if fuse_readpages() failed in it's + initialization. Bug found and original patch from Alexander + Zarochentsev + + * For linux kernels >=2.6.18 (2.6.19 if using the fuse module from + the kernel tree) the statfs method will receive the path within + the filesystem on which the stat(v)fs syscall was called + + * fusermount: try to modprobe fuse module if invoked by root and + unable to open device. This is needed with udev, since the device + node will be created only when the module is inserted, hence + module autoloading won't work. Reported by Szakacsits Szabolcs + +2006-07-30 Miklos Szeredi + + * fusermount: if selinux is active, restore the original file's + security context in unmount_rename(). Redhat bugzilla id 188561. + Patch from Yves Perrenoud + + * Add POSIX file locking operation to high level library + + * Initialize context for unlink of hidden files on umount. Bug + reported by Tim Stoakes + +2006-07-14 Miklos Szeredi + + * Multiple release() calls can race with each other, resulting in + the hidden file being deleted before the last release finishes. + Bug found and patch tested by Mark Huijgen + +2006-07-05 Miklos Szeredi + + * fusermount: if /dev/fuse doesn't exist, suggest modprobing fuse; + this makes sense on systems using udev. Reported by Szakacsits + Szabolcs + +2006-06-29 Miklos Szeredi + + * Released 2.6.0-pre3 + +2006-06-29 Miklos Szeredi + + * Support in kernel module for file locking and interruption. The + same functionality is available in official kernels >= 2.6.18 + +2006-06-28 Miklos Szeredi + + * Add POSIX file locking support + + * Add request interruption + +2006-06-06 Miklos Szeredi + + * Add missing pthread_rwlock_destroy(). Patch from Remy Blank + +2006-06-05 Remy Blank + + * lib: canonicalize mount point in fuse_helper_opt_proc() so that + unmounting succeeds even if mount point was relative. + +2006-06-04 Csaba Henk + + * lib: fix emergency umount in helper.c when malloc fails. + (The way it was done would end up in a segfault.) + +2006-06-01 Csaba Henk + + * lib: adjust threading related compiler flags. + Switch to "-pthread" from "-lpthread" as that's the preferred + one on several platforms. Consulted with Terrence Cole and + Miklos Szeredi + +2006-05-08 Miklos Szeredi + + * lib: search fusermount in installation directory (bindir) as + well as in PATH. + +2006-05-03 Miklos Szeredi + + * lib: fix compilation if CLOCK_MONOTONIC is not defined. + Reported by Christian Magnusson + +2006-04-23 Csaba Henk + + * lib: make FreeBSD mount routine recognize if kernel features + backgrounded init and if it does, run the mount util in foreground + (similarly to Linux) + +2006-04-21 Miklos Szeredi + + * kernel: fix fput deadlock fix, the lockless solution could lead + to "VFS: busy inodes after umount..." + + * kernel: fix race between checking and setting file->private_data + for the device. Found by Al Viro + +2006-04-11 Miklos Szeredi + + * kernel: remove request pool, instead allocate requests on + demand. Account the number of background requests, and if they go + over a limit, block the allocation of new requests. + + * kernel: fix deadlock if backgrounded request holds the last + reference to the super block + + * kernel: don't use fuse_reset_request() during direct I/O + +2006-04-06 Csaba Henk + + * lib: Let FreeBSD mount option parsing routine recognize "no" + prefixes for FUSE specific options as well + +2006-04-01 Miklos Szeredi + + * lib: Add missing rwlock initialization. Patch by Ryan Bradetich + +2006-03-17 Miklos Szeredi + + * API changes: + + * fuse_main(), fuse_setup() and fuse_new() have an additionl + user_data parameter + + * fuse_mount() returns a 'struct fuse_chan' pointer instead of a + file descriptor + + * fuse_unmount() receives a 'struct fuse_chan' pointer. It + destroys the given channel + + * fuse_teardown() no longer has a file descriptor parameter + + * new exported functions: fuse_session_remove_chan(), + fuse_get_session(), fuse_daemonize() + + * fuse_chan_recv() may now return a new channel which will be used + to send the reply + +2006-03-16 Miklos Szeredi + + * Released 2.6.0-pre2 + +2006-03-16 Miklos Szeredi + + * Don't unmount if already unmounted. This fixes a problem seen + in the following situation: Lazy unmount a busy filesystem; Mount + a new one in top; When the first finally unmounts, the second also + unmounts. Reported by Franco Broi + +2006-03-15 Miklos Szeredi + + * lowlevel lib: use indirect function calls instead of a + switch/case construct. Besides increased efficiency it helps + maintainability & readability too. Patch from Florin Malita + +2006-03-13 Miklos Szeredi + + * kernel: replace global spinlock with a per-connection spinlock + +2006-03-10 Miklos Szeredi + + * Fix source compatibility breakage for fuse_unmount(). Report + from Yura Pakhuchiy + +2006-03-02 Miklos Szeredi + + * Fix O_ASYNC handling in fuse_dev_release(). From Jeff Dike + +2006-03-01 Miklos Szeredi + + * Add O_ASYNC and O_NONBLOCK support to FUSE device. Patch by + Jeff Dike + + * Renamed fuse_chan_receive() to fuse_chan_recv() and changed + interface to return -errno in case of error. + +2006-03-01 Csaba Henk + + * libfuse: pass device file descriptor to fuse_unmount(), rewrite + FreeBSD implementation so that it uses libc (sysctl backed) instead + of an embdedded script (kmem backed). Adjust the control flow of + hello_ll so that device doesn't get closed before unmount attempt. + +2006-02-25 Miklos Szeredi + + * Lowlevel lib: return all-zero statvfs data if filesystem doesn't + implement method. This is needed on FreeBSD, and nicer on Linux + too. Highlevel lib already did this. Reported by Csaba Henk + + * Fix negative entry handling. There was a bug, that negative + lookups with timeouts (nodeid == 0) returned -EIO. + +2006-02-23 Miklos Szeredi + + * Fix race between RELEASE and UNLINK, which might leave + .fuse_hidden* files around + +2006-02-21 Miklos Szeredi + + * fusexmp_fh: implement flush() method and call close() on the + open file descriptor. This is needed if used on an NFS + filesystem, which buffers data until file is closed. Franco Broi + spotted the situation when 'cp -p' failed to set the modification + time because of this. + +2006-02-20 Miklos Szeredi + + * Released 2.6.0-pre1 + +2006-02-19 Miklos Szeredi + + * libfuse: fix use-after-free bug in interruptred reply_entry(). + Patch from John Muir + + * libfuse: fix wrong symbol versioning for fuse_mount. Debian bug + ID: 352631. Found by Stéphane Rosi + +2006-02-17 Miklos Szeredi + + * Lowlevel lib: Unify fuse_dirent_size() and fuse_add_dirent() + into a single function fuse_add_direntry(). This cleans up the + interface and makes it possible to do stacking. + +2006-02-16 Miklos Szeredi + + * Fix rare race betweeen abort and release caused by failed iget() + in fuse_create_open(). + + * Add 'ac_attr_timeout' option e.g. for filesystems which do their + own attribute caching. + +2006-02-15 Miklos Szeredi + + * Work around FreeBSD runtime linker "feature" which binds an old + version of a symbol to internal references if the symbol has more + than one version. This resulted in infinite recursion in + fuse_lowlevel_new_compat25(). + +2006-02-10 Csaba Henk + + * Refine clock_gettime() querying so that linker options + shall be set as it's appropriate for the target platform. + +2006-02-09 Miklos Szeredi + + * Fix udev rule syntax. Reported by Nix + +2006-02-08 Miklos Szeredi + + * In some cases udev rule seems to be ineffective when installed + as 40-fuse.rules but work as 60-fuse.rules. Reported by John Hunt + +2006-02-03 Miklos Szeredi + + * Fix compilation when build directory is different from source + directory. Reported by Frédéric L. W. Meunier + +2006-02-02 Miklos Szeredi + + * Fix even bigger bug introduced in fix for request_end() on + 2006-01-14. Reported by Gal Rosen + +2006-01-30 Miklos Szeredi + + * highlevel-lib: add 'auto_cache' option. This caches file data + based on modification time and size + +2006-01-20 Miklos Szeredi + + * Sanitize storage type and help message in mount_bsd.c. Patch + from Csaba Henk + + * fuse_opt: add new helper constants FUSE_OPT_KEY_KEEP and + FUSE_OPT_KEY_DISCARD + + * Add options 'max_readahead', 'sync_read' and 'async_read' + + * Kernel ABI version 7.6: + + * Negotiate the 'max_readahead' value and 'async_read' flags with + userspace in the INIT method + + * Add connection info to ->init() methods to both lowlevel and + highlevel API + + * Fall back to synchronous read() behavior if either library or + userspace filesystem is using the old interface version. This is + needed so non-updated filesystems won't be confused by the + different read() behavior + +2006-01-19 Miklos Szeredi + + * lib: if "fsname=" option was given, pass it to fusermount + + * fuse_opt: add new fuse_opt_insert_arg() function, which is + needed by filesystems to implement some argument manipulations + correctly + + * fuse_opt: fix memory leak in handling "--" option + +2006-01-18 Miklos Szeredi + + * kernel: fix detection of case when fuse is not configured into + the kernel either as module or built-in + + * fuse_opt.h: fix incompatibility with C++ compilers by renaming + 'template' structure member to 'templ'. Reported by Takashi Iwai + + * fuse.h: fix compatibility bugs. Patch by Yura Pakhuchiy + + * kernel: support version 2.6.16 (i_sem -> i_mutex) + +2006-01-16 Miklos Szeredi + + * Added (again) asynchronous readpages support + + * Each connection now shows up under /sys/fs/fuse/connections + + * Connection attributes exported to sysfs: 'waiting' number of + waiting requests; 'abort' abort the connection + + * Connection may be aborted through either the sysfs interface or + with 'umount -f mountpoint' + +2006-01-14 Miklos Szeredi + + * Released 2.5.0 + +2006-01-14 Miklos Szeredi + + * kernel: fix a couple of bugs + + * Order of request_end() and fuse_copy_finish() was wrong. + Posthumous note: Franco Broi managed to exploit this, though it + seemed quite impossible + + * request_end() used request pointer after decrementing refcount + + * Clearing ->connected or ->mounted connection flags could race + with setting other bitfields not protected with a lock + +2006-01-10 Miklos Szeredi + + * kernel: add necessary compile flags for 2.4.X/x86_64. + Report from Sean Ziegeler + +2006-01-09 Miklos Szeredi + + * Released 2.5.0-pre2 + +2006-01-09 Miklos Szeredi + + * Applied patch from Csaba Henk, to update mount_bsd to new + fuse_mount() semantics + + * Ignore auto,noauto,... options in mount.fuse. Reported by Frank + Steiner and Don Taber + + * fusermount: add 'dirsync' mount option + +2006-01-07 Miklos Szeredi + + * Improved help reporting and added version reporting to library + +2006-01-06 Miklos Szeredi + + * Change working directory to "/" even if running in the + foreground. Patch from Jonathan Brandmeyer + + * Changed lots of functions to use 'struct fuse_args' instead of + separate argc and argv + + * Added fuse_parse_cmdline(), fuse_set_signal_handlers() and + fuse_remove_signal_handlers() functions, so that it's now pretty + easy to get all the functionality of fuse_main() with a filesystem + using the lowlevel API. + +2006-01-02 Miklos Szeredi + + * mount.fuse: the 'user' option should be ignored. Report and + solution from Mattd. + + * mount.fuse: export PATH in the right place. Report and patch + from Hannes Schweizer + +2005-12-16 Miklos Szeredi + + * Clean up the option parsing interface slightly, by creating an + "argument list" structure, that contains the argument vector and + count + +2005-12-15 Miklos Szeredi + + * fusermount: check if /mnt/mtab is a symlink and don't modify it + in that case + + * kernel: simplify request size limiting. INIT only contains + maximum write size, maximum path component size remains fixed at + 1024 bytes, and maximum xattr size depends on read buffer. + +2005-12-14 Miklos Szeredi + + * Fix readdir() failure on x86_64, of 32bit programs compiled + without largefile support. Bug report and help from Anthony + Kolasny + + * If lookup returns invalid mode, return -EIO instead of creating + a regular file + + * Add current output argument vector to option processing + function + +2005-12-12 Miklos Szeredi + + * Fix stale code in ifdef FreeBSD. Patch from Csaba Henk + +2005-12-09 Miklos Szeredi + + * Released 2.5.0-pre1 + +2005-12-09 Miklos Szeredi + + * libfuse: added option parsing interface, defined in + . + +2005-12-07 Miklos Szeredi + + * Return EIO for file operations (read, write, fsync, flush) on + open files whose inode has become "bad". Inodes will be marked + "bad" if their type changes. Bug report by Csaba Henk + +2005-12-06 Miklos Szeredi + + * Use bigger request buffer size. write() did not work on archs + with > 4k page size, Bug report by Mark Haney + + * ABI version 7.5: + + * Extend INIT reply with data size limits + +2005-12-02 Miklos Szeredi + + * Fix memory leak in fuse_read_cmd()/fuse_process_cmd(). Bug + reported by Vincenzo Ciancia + + * Handle exit-by-umount in fuse_read_cmd() + +2005-11-29 Miklos Szeredi + + * Check if '-msoft-float' option is supported by compiler when + configuring for a 2.4.x kernel. Bug report by Mark Haney + + * In multithreaded loop send a TERM signal to the main thread if + one of the other threads exit. Needed on FreeBSD for a clean exit + on umount. Should not cause any harm on Linux either + +2005-11-28 Miklos Szeredi + + * Fix bug in 32-bit file handle compatibility + +2005-11-27 Miklos Szeredi + + * Block TERM, INT, HUP and QUIT signals in all but the main + thread. According to POSIX it's not specified which thread will + receive these signals. + + * Kernel changes: + + * Check for directory aliasing on mkdir, not just on lookup + + * Check for special node ID values in create+open operation + + * Sync with -mm: readv, writev, aio_read and aio_write methods + added to file operations + + * Cleanups: lookup code, page offset calculation + + * ABI stepped to 7.4, changes: + + * frsize member added to fuse_kstatfs structure + + * added support for negative entry caching: on lowlevel API if + fuse_entry_param::ino is set to zero in reply to a lookup request, + the kernel will cache the dentry for the specified amount of time. + + * libfuse: added 'negative_timeout' option: specifies how much + negative entries should be cached. Default is zero, to be + compatible with prior versions + +2005-11-22 Miklos Szeredi + + * Add detection of mainline FUSE code in running kernel + +2005-11-21 Miklos Szeredi + + * Don't use async cancelation in multithreaded loop. This makes + it more portable to systems where read() is not async cancel safe. + Report from Andriy Gapon + +2005-11-20 Miklos Szeredi + + * Warn if API version 11 compatibility is requested + +2005-11-17 Miklos Szeredi + + * More FreeBSD merge + + * fusermount: don't allow mountpoints with '\n', '\t', or '\\' in + them, because it corrupts /etc/mtab. Found by Thomas Biege + CVE-2005-3531 + + * libfuse: don't use system() to invoke 'fusermount -u ...' + because it breaks mountpoints with spaces in them into multiple + arguments + +2005-11-16 Miklos Szeredi + + * Merge library part of FreeBSD port. Patch by Csaba Henk + +2005-11-11 Miklos Szeredi + + * Use 64bit type for file handle, so the full range supported by + the kernel interface is available to applications + +2005-11-10 Miklos Szeredi + + * Moved mountpoint argument checking from fuse_parse_cmdline() to + fuse_mount() in preparation to FreeBSD merge. + +2005-11-08 Miklos Szeredi + + * Remove unneeded close() from fuse_teardown(). Spotted by Csaba + Henk. + +2005-11-07 Miklos Szeredi + + * Make the statfs change backwards compatible. + +2005-11-06 Miklos Szeredi + + * Change ->statfs() method to use 'struct statvfs' instead of + 'struct statfs'. This makes the API more portable since statvfs() + is defined by POSIX. + +2005-10-28 Miklos Szeredi + + * Add fgetattr() method, which currently will only be called after + a successful call to a create() method. + +2005-10-26 Miklos Szeredi + + * Change kernel ABI version to 7.3 + + * Add ACCESS operation. This is called from the access() system + call if 'default_permissions' mount option is not given, and is + not called on kernels 2.4.* + + * Add atomic CREATE+OPEN operation. This will only work with + 2.6.15 (presumably) or later Linux kernels. + + * Add ftruncate() method. This will only work with 2.6.15 + (presumably) or later Linux kernels. + + * Fix kernel module compile if kernel source and build directories + differ. Report and initial patch by John Eastman + +2005-10-18 Miklos Szeredi + + * lib: optimize buffer reallocation in fill_dir. + +2005-10-17 Miklos Szeredi + + * Released 2.4.1 + +2005-10-14 Miklos Szeredi + + * libfuse: add debug for write result (by Shaun Jackman) and + warnings for too large read/write result + +2005-10-11 Miklos Szeredi + + * Spelling fixes, thanks to Ioannis Barkas + +2005-10-10 Miklos Szeredi + + * fuse_common.h: use extern "C". Thanks to Valient Gough for the + patch + +2005-10-07 Miklos Szeredi + + * highlevel-lib: init() and destroy() methods didn't have an + initialized fuse_context. Bug reported by Tim Stoakes + +2005-10-04 Miklos Szeredi + + * Released 2.4.0 + +2005-10-03 Miklos Szeredi + + * Add documentation to fuse_lowlevel.h + + * API cleanups: + + * Remove definitions of unused FATTR_CTIME / FUSE_SET_ATTR_CTIME + + * Move fuse_mount() and fuse_unmount() to fuse_common.h + + * Change the return type of fuse_reply_none() from int to void. + +2005-09-30 Miklos Szeredi + + * kernel: NFS exporting leaked dentries. Bug found and fixed by + Akshat Aranya. + +2005-09-29 Miklos Szeredi + + * fusermount: fix error message, when unable to open /dev/fuse. + Report by Balázs Pozsár + +2005-09-28 Miklos Szeredi + + * UClibc fixes from Christian Magnusson + +2005-09-27 Miklos Szeredi + + * Added NAME="%k" to util/udev.rules. Fix by Mattias Wadman. + +2005-09-26 Miklos Szeredi + + * Released 2.4.0-rc1 + +2005-09-26 Miklos Szeredi + + * fusermount: allow user umount in the case when /etc/mtab is a + symlink to /proc/mounts. Reported by Balázs Pozsár. + +2005-09-23 Miklos Szeredi + + * Check for special node ID values in lookup and creation + +2005-09-22 Miklos Szeredi + + * Slight optimization in returning EINVAL error in case of an open + with O_DIRECT flag. + +2005-09-20 Miklos Szeredi + + * Remove '--enable-auto-modprobe' configure flag. Module + auto-loading is now handled by the kernel. + +2005-09-15 Miklos Szeredi + + * Install UDEV rule file, so /dev/fuse is created with mode 0666. + Help from Jens M. Noedler. + +2005-09-14 Miklos Szeredi + + * Add memory cleanup on thread exit + +2005-09-13 Miklos Szeredi + + * Set umask to zero in fusexmp and fusexmp_fh, so that + files/directories are created with the requested mode. + +2005-09-12 Miklos Szeredi + + * Don't ignore read error in multithreaded loop + +2005-09-08 Miklos Szeredi + + * Released 2.4.0-pre2 + +2005-09-08 Miklos Szeredi + + * Revert lock and access operations. Postpone these until 2.5. + +2005-09-02 Miklos Szeredi + + * Fix compile warning on 2.6.13 and later + + * Fix compilation on old kernels + +2005-08-19 Miklos Szeredi + + * lib: always refresh directory contents after rewinddir() to + conform to SUS. Bug found by John Muir. + +2005-08-15 Miklos Szeredi + + * Released 2.4.0-pre1 + +2005-08-14 Miklos Szeredi + + * lib: cleaned up (or messed up, depending on your POV) the low + level library API. Hopefully this is close to the final form. + +2005-08-05 Miklos Szeredi + + * fusermount: don't allow empty mountpoint argument, which defeats + automatic umounting in fuse_main(). Bugreport by Václav Jůza + +2005-08-03 Miklos Szeredi + + * fix warnings in fuse.h and fuse_lowlevel.h if -Wshadow compiler + option is used (Paul Alfille). + +2005-08-02 Miklos Szeredi + + * highlevel-lib: added mount options "attr_timeout" and + "entry_timeout". These options control the length of time file + attributes and entries (names) are cached. Both default to 1.0 + second. + + * kernel: correctly handle zero timeout for attributes and entries + +2005-08-01 Miklos Szeredi + + * Added missing symbols to versionscript (Joshua J. Berry) + + * kernel: implement two flags, open can set: 'direct_io' and + 'keep_cache'. These correspond exactly to mount options + 'direct_io' and 'kernel_cache', but allow a per-open setting. + + * Move 'direct_io' and 'kernel_cache' mount option handling to + userspace. For both mount options, if the option is given, then + the respective open flag is set, otherwise the open flag is left + unmodified (so the filesystem can set it). + + * lib (highlevel): make open method optional + +2005-07-28 Miklos Szeredi + + * kernel: invalidate attributes for read/readdir/readlink + operations + + * kernel: detect newer UML kernels + +2005-07-26 Miklos Szeredi + + * Make the installation path of fuse.ko and mount.fuse + configurable through INSTALL_MOD_PATH and MOUNT_FUSE_PATH + environment variables. Requirement and help from Csaba Henk. + +2005-07-22 Miklos Szeredi + + * Fix bug, that causes filesystem requests to hang when unique + request counter becomes negative. This happens after + 2,147,483,648 operations, so most people won't care. Thanks to + Franco Broi for the report and testing. + +2005-07-21 Miklos Szeredi + + * Don't change mtime/ctime/atime to local time on read/write. + Bug reported by Ben Grimm + + * Install fuse_common.h and fuse_lowlevel.h. Report by Christian + Magnusson + + * fusermount: use getopt_long() for option parsing. It allows the + use of '--' to stop argument scanning, so fusermount can now + operate on directories whose names begin with a '-'. Patch by + Adam Connell + +2005-07-15 Miklos Szeredi + + * fusermount: add '-v', '--version' and '--help' options + + * add inode based API + +2005-07-12 Miklos Szeredi + + * lib: don't block signals in worker threads. Problem noticed by + Usarin Heininga + +2005-07-07 Miklos Szeredi + + * lib: don't allow both 'allow_other' and 'allow_root' options to + be given + +2005-07-06 Miklos Szeredi + + * fusermount: check if mountpoint is empty (only '.' and '..' for + directories, and size = 0 for regular files). If "nonempty" + option is given, omit this check. This is useful, so users don't + accidentally hide data (e.g. from backup programs). Thanks to + Frank van Maarseveen for pointing this out. + + * kernel: check if mandatory mount options ('fd', 'rootmode', + 'user_id', 'group_id') are all given + + * lib: simplify 'readdir_ino' handling + + * lib: add mount options 'umask=M', 'uid=N', 'gid=N' + +2005-07-03 Miklos Szeredi + + * kernel: clean up 'direct_io' code + +2005-06-28 Miklos Szeredi + + * Add 'mount.fuse' written by Petr Klima + + * '/dev/fuse' is created by 'make install' if does not yet exist + +2005-06-20 Miklos Szeredi + + * Fix UCLIBC compile error. Patch by Christian Magnusson + +2005-06-08 Miklos Szeredi + + * Enable the auto-loading of the module via access to the + corresponding device file. Patch by Takashi Iwai. + + * Allow mounting a regular file (over a regular file) for + unprivleged users. + + * Do not create temporary device file. Require "/dev/fuse" to + exist, and be readable/writable by the mounting user. + +2005-06-02 Miklos Szeredi + + * Released 2.3.0 + +2005-06-02 Miklos Szeredi + + * Fix serious information leak: if the filesystem returns a short + byte count to a read request, and there are non-zero number of + pages which are not filled at all, these pages will not be zeroed. + Hence the user can read out previous memory contents. Found by + Sven Tantau. + +2005-05-27 Miklos Szeredi + + * Add "readdir_ino" mount option, which tries to fill in the d_ino + field in struct dirent. This mount option is ignored if "use_ino" + is used. It helps some programs (e.g. 'pwd' used over NFS from a + non-Linux OS). Patch by David Shaw. + +2005-05-12 Miklos Szeredi + + * Released 2.3-rc1 + +2005-05-12 Miklos Szeredi + + * File save in krusader and other editors doesn't work with sshfs, + because open() is interrupted by a periodic signal, and open() + restarts forever, without any progress. This could just be fixed + in open(), but the problem is more generic: if signals are + received more often than the filesystem can get the request to + userspace, it will never finish. This is probably only a + theoretical problem, nevertheless I'm removing the possibility to + interrupt requests with anything other than SIGKILL, even before + being sent to userspace. Bugreport by Eduard Czimbalmos. + +2005-05-09 Miklos Szeredi + + * libfuse: add "tree_lock" rwlock, that is locked for write in + rename, unlink and rmdir, and locked for read in all other + operations. This should fix the rename/release race reported by + Valient Gough and others. The solution is very coarse, a finer + grained locking scheme could be implemented, but it would be much + more complex. Let's see whether this is good enough. + +2005-05-09 Miklos Szeredi + + * Released 2.3-pre7 + +2005-05-08 Miklos Szeredi + + * Better fix for out of order FORGET messages. Now the + LOOKUP/FORGET messages are balanced exactly (one FORGET can + balance many lookups), so the order no longer matters. This + changes the kernel ABI slightly, but the library remains backward + compatible. + +2005-05-06 Miklos Szeredi + + * Fix abort for out of order FORGET messages. Again. Spotted by + Franco Broi again. Sorry :) + +2005-04-29 Miklos Szeredi + + * Released 2.3-pre6 + +2005-04-29 Miklos Szeredi + + * Make fusermount work with fuse kernel modules not yet supporting + the "group_id" option (added for the purpose of stricter + permission checking). + +2005-04-28 Miklos Szeredi + + * Check for hard-linked directories in lookup. This could cause + problems in the VFS, which assumes that such objects never exist. + + * Make checking of permission for other users more strict. Now + the same privilege is required for the mount owner as for ptrace + on the process performing the filesystem operation. + +2005-04-23 Miklos Szeredi + + * Released 2.3-pre5 + +2005-04-22 Miklos Szeredi + + * Add -msoft-float to kernel module compile flags for 2.4.X. This + is needed on certain architectures. Report from Chris Kirby + + * Fix buggy behavior of open(..., O_CREAT|O_EXCL) if interrupted. + Reported by David Shaw + + * Remove "allow_root" option from kernel module, and implement + it's functionality in the library + + * Fix Oops caused by premature release of fuse_conn. Clean up + related code, to be more readable + + * Sendfile should not use page cache if "direct_io" mount option + is given + +2005-04-08 Miklos Szeredi + + * Fix Oops in case of nfs export. Spotted by David Shaw + + * Fix another Oops in case of write over nfs with direct_io turned + on. Again spotted by David Shaw + +2005-04-07 Miklos Szeredi + + * Released 2.3-pre4 + +2005-04-07 Miklos Szeredi + + * lib: finalized new readdir() interface, which now supersedes the + getdir() method. + +2005-04-03 Miklos Szeredi + + * Released 2.3-pre3 + +2005-04-03 Miklos Szeredi + + * Implement backward compatibility with version 5 kernel ABI + +2005-04-01 Miklos Szeredi + + * Released 2.3-pre2 + +2005-04-01 Miklos Szeredi + + * kernel: fix dirent offset handling + + * lib: add readdir and releasedir methods + + * lib: use fh field of fuse_file_info in opendir, readdir, + releasedir and fsyncdir methods + + * lib: check kernel API version and bail out of it's old. This + will be properly fixed in the next release + +2005-03-31 Miklos Szeredi + + * Released 2.3-pre1 + +2005-03-31 Miklos Szeredi + + * kernel API: add padding to structures, so 64bit and 32bit + compiler will return the same size + + * kernel API: add offset field to fuse_dirent. This will allow + more sophisticated readdir interface for userspace + + * kernel API: change major number to 6 + + * kernel: fix warnings on 64bit archs + + * kernel: in case of API version mismatch, return ECONNREFUSED + +2005-03-24 Miklos Szeredi + + * kernel: trivial cleanups + +2005-03-21 Miklos Szeredi + + * Add fsyncdir() operation + +2005-03-19 Miklos Szeredi + + * kernel: add locking to background list (fixes previous fix) + +2005-03-18 Miklos Szeredi + + * kernel: fix bug which could cause leave busy inodes after + unmount, and Oops. + +2005-03-08 Miklos Szeredi + + * examples: add -lpthread to link flags to work around valgrind + quirk + + * lib: don't exit threads, so cancelation doesn't cause segfault + +2005-03-04 Miklos Szeredi + + * kernel: fix nasty bug which could cause an Oops under certain + situations. Found by Magnus Johansson + +2005-02-28 Miklos Szeredi + + * libfuse: added opendir() method. This can be used in case + permission checking in getdir() is too late. Thanks to Usarin + Heininga for pointing out this deficiency + + * libfuse: added init() and destroy() methods to fuse_operations + + * kernel: llseek() method for files and directories made explicit + + * kernel: fixed inode leak in NFS export in case of nodeid + wrapping + +2005-02-15 Miklos Szeredi + + * libfuse: clean up some unitialized memory found with valgrind + + * Add -lpthread to Libs in fuse.pc. Valgrind seems to need an + explicitly linked libpthread for applications + +2005-02-10 Miklos Szeredi + + * fusermount: set umask, otherwise /etc/mtab will have + unpredictable permission. Spotted by Jindrich Kolorenc + + * fusermount: set owner and group of /etc/mtab to original values + on unmount + + * libfuse: add 'use_ino' option to help. Patch by Valient Gough + +2005-02-07 Miklos Szeredi + + * Cleaned up directory reading (temporary file is not used) + +2005-02-02 Miklos Szeredi + + * Released 2.2 + +2005-02-02 Miklos Szeredi + + * Fix possible race when operation is interrupted + +2005-01-28 Miklos Szeredi + + * Fix compilation on 2.6.7 + +2005-01-26 Miklos Szeredi + + * Released 2.2-pre6 + +2005-01-26 Miklos Szeredi + + * Fix bug in link() operation which caused the wrong path to be + passed as the first argument. Found by Anton Altaparmakov + +2005-01-21 Miklos Szeredi + + * LIB: fix double reply in readdir operation + + * fusermount: fix uid checking bug. Patch by Adam Connell + + * KERNEL: fix compile on various RedHat patched 2.4 kernels. + Patch by Keshava Gowda + +2005-01-20 Miklos Szeredi + + * KERNEL: provide correct llseek semantics for fuse device (fixes + a bug on Progeny 2.4.20 kernel). Reported by Valient Gough + +2005-01-20 Miklos Szeredi + + * Released 2.2-pre5 (matches kernel 2.6.11-rc1-mm2) + +2005-01-18 Miklos Szeredi + + * KERNEL ABI: remove GETDIR operation, and add OPENDIR, READDIR + and RELEASEDIR. This ends the ugly hack of passing a file + descriptor to the kernel, and actually makes the code simpler. + +2005-01-17 Miklos Szeredi + + * Released 2.2-pre4 + +2005-01-17 Miklos Szeredi + + * fusermount: remove capability setting, which was the cause of + problems for some users. It seems that FS related capabilities + are removed by setfsuid(), so this isn't even needed. + +2005-01-15 Miklos Szeredi + + * fix compilation on 2.4 kernels (reported by Valient Gough) + + * fix failure to unmount bug (found by David Shaw) + + * fusermount: improve parsing of /etc/fuse.conf + +2005-01-13 Miklos Szeredi + + * Remove 'mount_max' and 'user_allow_other' module options. These + are now checked by fusermount, and can be set in /etc/fuse.conf + + * KERNEL: change check for fsid == 0 to capable(CAP_DAC_OVERRIDE) + +2005-01-11 Miklos Szeredi + + * KERNEL: fix possible inode allocation problem, where + sizeof(struct inode) is not aligned (found by Mike Waychison) + + * KERNEL: use new follow_link/put_link methods + + * KERNEL: cosmetic fixes + +2005-01-10 Miklos Szeredi + + * Released 2.2-pre3 + +2005-01-10 Miklos Szeredi + + * Add missing code that was accidently left out + +2005-01-09 Miklos Szeredi + + * Released 2.2-pre2 + +2005-01-09 Miklos Szeredi + + * Change "uid" mount option to "user_id" to avoid confusion with a + mount option "uid" commonly used by many filesystems + +2005-01-09 Miklos Szeredi + + * Released 2.2-pre1 + +2005-01-09 Miklos Szeredi + + * If FUSE is configured in the kernel, don't build it by default + +2005-01-07 Miklos Szeredi + + * Compile fix by Christian Magnusson + +2005-01-05 Miklos Szeredi + + * Fix compilation for 2.6.{0-5} kernels + +2005-01-04 Miklos Szeredi + + * KERNEL: if request is interrupted, still keep reference to used + inode(s) and file, so that FORGET and RELEASE are not sent until + userspace finishes the request. + + * remove /{sys,proc}/fs/fuse/version, and instead add an INIT + request with the same information, which is more flexible, + simpler, works on embedded systems. + +2004-12-16 Miklos Szeredi + + * KERNEL ABI: update interface to make it independent of type + sizes. This will help on 64 bit architectures which can run + legacy 32 bit applications. + + * KERNEL ABI: add "len" field to request headers. This will allow + sending/receiving requests in multiple chunks. + + * KERNEL: handle file type change more intelligently + + * LIB: "-o debug" option should disable backgrounding (fix by + Fabien Reygrobellet) + +2004-12-13 Miklos Szeredi + + * KERNEL: invalidate dentry/attributes if interrupted request + could leave filesystem in an unknown state. + +2004-12-12 Miklos Szeredi + + * KERNEL: lots of cleanups related to avoiding possible deadlocks. + These will cause some regressions, but stability is considered + more important. If any of these features turns out to be + important, it can be readded with the deadlock problems addressed. + + * Make all requests interruptible (only with SIGKILL currently). + This can be used to break any deadlock produced by the userspace + filesystem accessing it's own exported files. The RELEASE request + is special, because if it's interrupted before sending it to + userspace it is still sent, but the reply is not awaited. + + * If request is interrupted before being sent to userspace, and if + it hasn't yet got any side effects, it is always restarted, + regardless of the SA_RESTART flag. This makes these interruptions + transparent to the process. + + * Remove shared-writable mmap support, which was prone to an + out-of-memory deadlock situation + + * Remove INVALIDATE userspace initiated request + + * Make readpages() synchronous. Asynchronous requests are + deadlock prone, since they cannot be interrupted. + + * Add readv/writev support to fuse device operations + + * Remove some printks, which userspace FS can use for a DoS + against syslog + + * Remove 'large_read' mount option from 2.6 in kernel, check it in + fusermount instead + + * LIB: improve compatibility with a fuse.h header installed in + ${prefix}/include which in turn includes the real header. + + * LIB: improve compatibility by defining fuse_main() (which is now + not used), so old configure scripts find it. + +2004-12-10 Miklos Szeredi + + * When mounting on a subdirectory of / don't duplicate slashes at + the beggining of path (spotted by David Shaw) + +2004-12-09 Miklos Szeredi + + * Fix bug causing garbage in mount options (spotted by David Shaw) + +2004-12-07 Miklos Szeredi + + * Add 'writepage' flag to 'fuse_file_info'. + + * More comments in fuse.h + + * Get rid of double underscores + +2004-12-04 Miklos Szeredi + + * Add -D_FILE_OFFSET_BITS=64 to cflags provided by pkg-config + + * helper.c: add -ho option, which only displays the options not + the usage header. This can be used by filesystems which have + their own options. + +2004-12-03 Miklos Szeredi + + * Add source compatibility to 2.1 and 1.1 APIs. To select betwen + versions simply define FUSE_USE_VERSION to 22, 21 or 11 before + including the fuse header + + * Add binary compatibility to 2.1 version of library with symbol + versioning + +2004-12-03 Miklos Szeredi + + * Released 2.1 + +2004-12-01 Miklos Szeredi + + * kernel: clean up writing functions + + * kernel: no allocation on write in direct_io mode + + * move linux/fuse.h to fuse_kernel.h + +2004-11-30 Miklos Szeredi + + * kernel: clean up reading functions + +2004-11-29 Miklos Szeredi + + * kernel: make readpage() uninterruptible + + * kernel: check readonly filesystem flag in fuse_permission + + * lib: don't die if version file not found and new style device + exists + + * lib: add '-r' option, which is short for '-o ro' + + * fusermount: simplify device opening + + * kernel: when direct_io is turend on, copy data directly to + destination without itermediate buffer. More efficient and safer, + since no allocation is done. + + * fusermount: fix warning if fuse module is not loaded + + * kernel: use /dev/fuse on 2.4 too + +2004-11-26 Miklos Szeredi + + * libfuse API change: open, read, write, flush, fsync and release + are passed a 'struct fuse_file_info' pointer containing the open + flags (open and release), and the file handle. Verion changed to + 3.0. + +2004-11-23 Miklos Szeredi + + * More cleanups in the kernel + + * The 10,229 charater device number has been assigned for FUSE + + * Version file checking fix (reported by Christian Magnusson) + + * fusermount: opening the fuse device now doesn't need /sys. + + * Optimize reading by controlling the maximum readahead based on + the 'max_read' mount option + + * fixes for UCLIBC (Christian Magnusson) + +2004-11-19 Miklos Szeredi + + * Cleaned up kernel in preparation for merge into mainline: + + * Use /sys/fs/fuse/version instead of /proc/fs/fuse/version + + * Use real device (/dev/fuse) instead of /proc/fs/fuse/dev + + * __user annotations for sparse + + * allocate individual pages instead of kmalloc in fuse_readdir, + fuse_read and fuse_write. + + * Fix NFS export in case "use_ino" mount option is given + + * Make libfuse and fusermount compatible with future versions + + * fusermount: properly add mount options to /etc/mtab + +2004-11-15 Miklos Szeredi + + * fusermount: do not resolve last component of mountpoint on if it + is '.' or '..'. This new path resolvation is now done on mount as + well as unmount. This enables relative paths to work on unmount. + + * fusermount: parse common mount options like "ro", "rw", etc... + + * Allow module params to be changed through sysfs + +2004-11-14 Miklos Szeredi + + * Released 2.1-pre1 + +2004-11-14 Miklos Szeredi + + * Fix bug in fuse_readpages() causing Oops in certain situations. + Bug found by Vincenzo Ciancia. + + * Fix compilation with kernels versions > 2.6.9. + +2004-11-11 Miklos Szeredi + + * Check kernel interface version in fusermount to prevent + strangeness in case of mismatch. + + * No need to allocate fuse_conn until actual mount happens + + * Fix potential race between umount and fuse_invalidate + + * Check superblock of proc file in addition to inode number + + * Fix race between request_send_noreply() and fuse_dev_release() + +2004-11-10 Miklos Szeredi + + * Separate configure for the kernel directory + + * Don't allow write to return more than 'count' + + * Extend kernel interface for future use + +2004-11-09 Miklos Szeredi + + * Fix 'makeconf.sh' to use autoreconf if available + +2004-11-08 Miklos Szeredi + + * Add ino argument to 'fuse_dirfil_t'. NOTE: This breaks source + compatibility with earlier versions. To compile earier versions + just add '-DFUSE_DIRFIL_COMPAT' compile flag or fix the source. + Do not use the "use_ino" mount flag with filesystems compiled with + FUSE_DIRFIL_COMPAT. + + * Add pkg-config support. To compile a FUSE based filesystem you + can do "gcc -Wall `pkg-config --cflags --libs fuse` myfs.c -o myfs" + or similar. Note, that the PKG_CONFIG_PATH environment variable + usually needs to be set to "/usr/local/lib/pkgconfig". + + * fuse.h is now installed in ${prefix}/include/fuse/ + +2004-11-02 Miklos Szeredi + + * Added "use_ino" mount option. This enables the filesystems to + set the st_ino field on files + +2004-11-01 Miklos Szeredi + + * Fix compile problems with ancient (<=2.4.18) kernels (reported + by Jeremy Smith) + + * Add "allow_root" mount option. Patch by Yaroslav Rastrigin + + * Clear the 'exited' flag when mail loop is finished + +2004-10-28 Miklos Szeredi + + * Make xattr functions work under 2.6 (bug found by Vincenzo + Ciancia) + +2004-10-26 Miklos Szeredi + + * Reset request in fuse_flush() (bugreport by David Shaw) + +2004-10-21 Miklos Szeredi + + * fuse_main() now does not exit on error, rather it returns an + error code + + * Exported __fuse_setup() and __fuse_teardown() functions, which + make it easier to implement a custom event loop. + + * Use daemon() call to background the filesystem after mounting. + This function closes the standard input, output and error and + changes the current working directory to "/". + +2004-10-14 Miklos Szeredi + + * Released 1.9 + +2004-10-09 Miklos Szeredi + + * Don't allow fuse_flush() to be interrupted (bug found by David + Shaw) + +2004-09-27 Miklos Szeredi + + * Add PID to fuse_context. Patch by Steven James + + * Change file handle type to 'unsigned long' in kernel interface + +2004-09-22 Miklos Szeredi + + * A slight API change: fuse_get_context() doesn't need the "fuse" + pointer, but the returned context contains it instead. The + fuse_get() function is not needed anymore, so it's removed. + + * Fix mounting and umounting FUSE filesystem under another FUSE + filesystem by non-root (bug spotted by Valient Gough) + +2004-09-21 Miklos Szeredi + + * Fix deadlock in case of memory allocation failure. Patch by + Christian Magnusson + +2004-09-16 Miklos Szeredi + + * Check memory allocation failures in libfuse + +2004-09-14 Miklos Szeredi + + * Check temporary file creation failure in do_getdir(). Bug + spotted by Terje Oseberg + +2004-09-13 Miklos Szeredi + + * Allow "large_read" option for 2.6 kernels but warn of deprecation + + * Make requests non-interruptible so race with FORGET is avoided. + This is only a temporary solution + + * Support compiling FUSE kernel module on 2.4.x UML kernels + +2004-09-09 Miklos Szeredi + + * Fix bug in case two FORGETs for the same node are executed in + the wrong order. Bug spotted and endured for months by Franco + Broi, and logfile for solution provided by Terje Oseberg + +2004-09-01 Miklos Szeredi + + * Add -D_REENTRANT to the compile flags + + * Add documentation of fuse internals by Terje Oseberg + +2004-08-16 Miklos Szeredi + + * Change release method to be non-interruptible. Fixes bug + causing missing release() call when program which has opened files + is killed (reported by Franco Broi and David Shaw) + +2004-07-29 Miklos Szeredi + + * Add fuse_invalidate() to library API + +2004-07-26 Miklos Szeredi + + * Check permissions in setattr if 'default_permissions' flag is + set. Bug spotted by Damjan Lango + +2004-07-24 Miklos Szeredi + + * 'large_read' mount option removed for 2.6 kernels, since the + default (dynamic read size) is better + + * Extend kernel API with file handles. A file handle is returned + by open, and passed to read, write, flush, fsync and release. + This is currently only used for debug output in the library. + + * Security changes: + + * Change the current directory to the mountpoint before checking + the permissions and mount filesystem on "." + + * By default don't modprobe the fuse module for non-root. The old + behavior can be restored with the '--enable-auto-modprobe' flag of + ./configure + + * By default don't allow shared writable mappings for non-root. + The old behavior can be restored with the 'user_mmap=1' module + parameter + +2004-07-23 Miklos Szeredi + + * Clean up mount option passing to fusermount and to fuse_new() + BEWARE: this changes the userspace API slightly, and the command + line usage of programs using fuse_main() + +2004-07-20 Miklos Szeredi + + * Optimize reading under 2.6 kernels by issuing multiple page + asynchronous read requests + +2004-07-18 Miklos Szeredi + + * Only use redirty_page_for_writepage() for kernels >= 2.6.6 + +2004-07-16 Miklos Szeredi + + * Separate directory entry and inode attribute validity timer + + * New write semaphore to stop page writeback during truncate + + * Fsync now waits for all writes to complete before sending the + request + + * Optimization: if a page is completely written by + fuse_commit_write(), clear the dirty flag and set the uptodate + flag for that page + + * Some memory cleanup at exit + +2004-07-13 Miklos Szeredi + + * Add FUSE_HARD_REMOVE flag, and '-i' option to fuse main, which + disable the "hide if open" behavior of unlink/rename. + + * If temporary buffer allocation fails in raw read, fall back to a + smaller buffer + +2004-07-12 Miklos Szeredi + + * Fix bug in do_open() in libfuse: open count was incremented + after the reply is sent so it could race with unlink/forget and + cause an abort. + +2004-07-08 Miklos Szeredi + + * When performing create or remove operation, refresh the parent's + attributes on next revalidate, as i_nlink (and maybe size/time) + could be inacurate. + + * Use redirty_page_for_writepage() in fuse_writepage() for skipped + pages (2.6 only) + + * Set set_page_dirty address space operation (2.6 only) + +2004-07-06 Miklos Szeredi + + * Minor fix in read: print debug info even if read size is zero + +2004-07-04 Miklos Szeredi + + * Fix race between truncate and writepage (fsx-linux now runs + without error) + +2004-07-02 Miklos Szeredi + + * Fix kernel hang on mkfifo under 2.4 kernels (spotted and patch + by Mattias Wadman) + + * Added option for direct read/write (-r) + + * Fix revalidate time setting for newly created inodes + + * Remove uid==0 check for '-x' option in fusermount (kernel checks + this) + + * fuse_main() only installs handlers for signals (out of INT, HUP, + TERM, PIPE), for which no handler has yet been installed + + * Add module option 'user_allow_other' which if set to non-zero + will allow non root user to specify the 'allow_other' mount option + ('-x' option of fusermount) + + * Fix deadlock between page writeback completion and truncate + (bug found by Valient Gough with the fsx-linux utility) + +2004-07-01 Miklos Szeredi + + * Change passing fuse include dir to 2.6 kernel make system more + robust (fixes compile problems seen on SuSE 9.1 with updated 2.6 + kernel) + +2004-06-30 Miklos Szeredi + + * Acquire inode->i_sem before open and release methods to prevent + concurrent rename or unlink operations. + + * Make __fuse_read_cmd() read only one command. This allows + multiplexing the fuse file descriptor with other event sources + using select() or poll() (patch by Jeff Harris) + + * Export 'exited' flag with __fuse_exited() (patch by Jeff Harris) + +2004-06-27 Miklos Szeredi + + * Fix file offset wrap around at 4G when doing large reads + +2004-06-24 Miklos Szeredi + + * Fix memory leak in open (Valient Gough) + +2004-06-24 Miklos Szeredi + + * Add "close after delete" support to libfuse (patch by Valient + Gough) + + * Cancel all worker threads before exit in multithreaded mode + +2004-06-23 Miklos Szeredi + + * Fix locking bugs + + * Don't send reply to RELEASE + + * Work with newer libtool (1.5a) + + * Check for st_atim member of struct stat + +2004-06-22 Miklos Szeredi + + * No request allocation needed on inode and file release + +2004-06-21 Miklos Szeredi + + * Fix possible inode leak in userspace in case of unfinished + lookup/mknod/mkdir/symlink/link operation. + +2004-06-20 Miklos Szeredi + + * Fix some races and cleanups in fuse_read_super() + +2004-06-19 Miklos Szeredi + + * Requests are allocated at open time + +2004-06-03 Miklos Szeredi + + * Build shared library as well as static (using libtool) + + * Change FUSE_MINOR_VERSION from 1 to 0. I know it's illegal but + there has not been a release with the previous minor number, and I + hope nobody is using it for anything. + + * Change fuse_main(), so that default behavior is to go into + background if mount is successful. '-f' and '-d' options disable + backgrounding. This fixes the "Why does my FUSE daemon hang?" + newbie complaint. + + * Cache ENOSYS (function not implemented) errors on *xattr, flush + and fsync + + * Don't call getdir method from open() only from first readdir(). + Open is sometimes just used to store the current directory + (e.g. find) + +2004-05-18 Miklos Szeredi + + * Added flush() call + +2004-05-04 Miklos Szeredi + + * Extended attributes support for 2.4 (patch by Cody Pisto) + +2004-04-20 Miklos Szeredi + + * Fixed parser with modversions (Mattias Wadman) + +2004-04-19 Miklos Szeredi + + * Added mount option parser to 2.4 build + +2004-04-13 Miklos Szeredi + + * Replaced binary mount data with text options + + * Show FUSE specific mount options in /proc/mounts + + * Check in fuse.h whether _FILE_OFFSET_BITS is set to 64 + +2004-04-09 Miklos Szeredi + + * Check some limits so userspace won't get too big requests + +2004-04-05 Miklos Szeredi + + * Kill compile warning + + * Upgraded user-mount patch for 2.6.5 + +2004-04-02 Miklos Szeredi + + * Add detection of user-mode-linux to configure + +2004-03-31 Miklos Szeredi + + * fixed zero size case for getxattr and listxattr + +2004-03-30 Miklos Szeredi + + * new fusermount flag '-z': lazy unmount, default is not lazy + + * Extended attributes operations added (getxattr, setxattr, + listxattr, removexattr) + +2004-03-25 Miklos Szeredi + + * If filesystem doesn't define a statfs operation, then an + all-zero default statfs is returned instead of ENOSYS + +2004-03-24 Miklos Szeredi + + * Add FS_BINARY_MOUNTDATA filesystem flag for kernels > 2.6.4 + +2004-03-09 Miklos Szeredi + + * Fix for uClinux (Christian Magnusson) + +2004-03-02 Miklos Szeredi + + * fuse_main() adds "-n progname" to the fusermount command line + + * More kernel interface changes: + + * Lookup/getattr return cache timeout values + +2004-02-25 Miklos Szeredi + + * Clean up option parsing in fuse_main() + + * Added fuse_get() function which returns the fuse object created + by fuse_main() + +2004-02-20 Miklos Szeredi + + * removed old way of mounting (fusermount mountpoint program) + + * more kernel interface changes: + + * added nanosecond precision to file times + + * removed interface version from mount data + + * added /proc/fs/fuse/version which contains MAJOR.MINOR + +2004-02-19 Miklos Szeredi + + * statfs library API changed to match other methods. Since this + is not backward compatible FUSE_MAJOR_VERSION is changed to 2 + + * kernel interface changes follow: + + * statfs changed to 64 bits, added 'bavail' field + + * add generation number to lookup result + + * optimized mknod/mkdir/symlink/link (no separate lookup is + needed) + + * rdev size increased to 32 bits for mknod + + * kernel interface version changed to 3.1 + +2004-02-18 Miklos Szeredi + + * user-mount upgraded for 2.6.3 kernel + +2004-02-17 Miklos Szeredi + + * Added user-mount.2.6.2-rc3.patch + + * Add FS_SAFE flag to fuse filesystem + + * fusermount should allow (un)mounting for non-root even if not + suid-root + +2004-02-12 Miklos Szeredi + + * Remove MS_PERMISSION mount flag (that means something else now) + +2004-02-10 Miklos Szeredi + + * Added check for i_size_read/write functions to configure.in + (patch by Valient Gough) + +2004-02-06 Miklos Szeredi + + * Fixed writing >= 2G files + + * Check file size on open (with generic_file_open()) + + * Readpage calls flush_dcache_page() after storing data + + * Use i_size_read/write for accessing inode->i_size + + * Make loopback mount of a fuse file work + +2004-02-04 Miklos Szeredi + + * Released 1.1 + +2004-01-29 Miklos Szeredi + + * Properly check if the inode exists in fuse_invalidate + +2004-01-27 Miklos Szeredi + + * Added -q option for fusermount + + * fuse_unmount() now uses -q option of fusermount, so no error is + printed if the cause of the program exit is that the filesystem + has already been unmounted + + * Fix i_nlink correctness after rmdir/unlink + +2004-01-26 Miklos Szeredi + + * Released 1.1-pre2 + +2004-01-26 Miklos Szeredi + + * Fix typo (thanks Marcos Dione) + + * Compile fixes for 2.4 kernels + +2004-01-23 Miklos Szeredi + + * Fix CONFIG_MODVERSIONS compile on 2.6 + +2004-01-22 Miklos Szeredi + + * Write all pending data before a RELEASE operation + + * Suppress 'Bad file descriptor' warning on exit + + * Replaced fusermount option '-d xxx' with '-n xxx' so it doesn't + get confused with '-d' of fuse_main() (sorry about this change) + + * New fusermount option '-l' which enables big reads. Big reads + are now disabled by default. + + * fuse_main() can accept fusermount arguments after a '--' + +2004-01-19 Miklos Szeredi + + * Support for exporting filesystem over NFS (see README.NFS) + +2004-01-14 Miklos Szeredi + + * Support non-blocking writepage on 2.6. This makes FUSE behave + much more nicely in low-memory situations + + * Fix 32-bit dev handling in getattr and mknod for 2.6 kernels. + (Note: the mknod method does not yet use 32bit device number) + +2004-01-13 Miklos Szeredi + + * Code cleanups + +2004-01-07 Miklos Szeredi + + * Released 1.1-pre1 + +2004-01-06 Miklos Szeredi + + * Integrated 2.6 kernel support patch by Michael Grigoriev + + * Improvements and cleanups for 2.6 kernels + +2004-01-05 Miklos Szeredi + + * Added -d option to fusermount + +2003-12-15 Miklos Szeredi + + * Added major+minor version to library API, and minor version to + kernel API + +2003-12-13 David McNab + + * Implemented fsync support in examples/example.py + + * Implemented 'fsync' and 'statfs' methods in python + interface + +2003-12-12 Miklos Szeredi + + * Make it compile on 2.4.19. + + * Add fsync operation (write file failed on xemacs & vi) + +2003-12-12 David McNab + + * Added distutils support to the python module, as per standard + python development practice + +2003-12-11 Miklos Szeredi + + * Add file locking for mount/unmount (based on patch by Valient + Gough) + +2003-12-11 David McNab + + * Python filesystem - was broken with python2.3, now fixed: + - changed PyTuple_* calls to PySequence_*, because os.lstat + is no longer returning a pure tuple + - changed PyInt_Check() calls to also call PyLong_Check, + to cover for cases (eg os.lstat) where longs are returned + - Added support for file 'release' handling, which IMO is + essential since this signals to a FS that writes to a file + are complete (and therefore the file can now be disposed of + meaningfully at the python filesystem's discretion) + - Added '__init__' handler to base Fuse class, which allows + your Python class to know the mountpoint and mount args, + as attributes myfs.mountpoint, myfs.optlist, myfs.optdict + + * General: + - added 'mount.fuse' script (in util/ dir), which is meant to be + symlinked from /sbin, and which allows FUSE filesystems to + be mounted with the 'mount' command, and listed in fstab; + also, mount arguments get passed to your filesystem + + +2003-11-04 Miklos Szeredi + + * Fix kernel version detection (again). Bugreport by Peter Levart + +2003-11-03 Miklos Szeredi + + * Applied read combining patch by Michael Grigoriev (tested by + Valient Gough and Vincent Wagelaar) + +2003-10-22 Miklos Szeredi + + * Mtab handling fix in fusermount by "Valient Gough" (SF patch + #766443) + +2003-10-13 Miklos Szeredi + + * Error code fixes in kernel module + +2003-10-04 Miklos Szeredi + + * kernel version detection fix + + * fusermount now uses "lazy" umount option + + * fusermount can use modprobe with module-init-tools + +2003-09-08 Miklos Szeredi + + * Integrated caching patch by Michael Grigoriev + + * Added "Filesystems" file with descriptions of projects using + FUSE + + * Added patch by Michael Grigoriev to allow compliation of FUSE + kernel module for 2.6 kernels + +2003-06-02 Miklos Szeredi + + * And another spec-file fix by Achim Settelmeier + +2003-05-26 Miklos Szeredi + + * Spec-file fix by Achim Settelmeier + +2003-03-10 Miklos Szeredi + + * Fix umount oops (found by Samuli Kärkkäinen) + +2003-03-05 Miklos Szeredi + + * Merge of fuse_redhat.spec and fuse.spec by Achim Settelmeier + +2003-03-04 Miklos Szeredi + + * Updated fuse.spec file (Achim Settelmeier) + +2003-02-19 Miklos Szeredi + + * Version 1.0 released + +2003-02-12 Miklos Szeredi + + * SuSE compilation fix by Juan-Mariano de Goyeneche + +2002-12-10 Miklos Szeredi + + * The release() VFS call is now exported to the FUSE interface + +2002-12-05 Miklos Szeredi + + * 64 bit file offset fixes in the fuse kernel module + + * Added function 'fuse_exit()' which can be used to exit the main + loop + +2002-12-03 Miklos Szeredi + + * Added _FILE_OFFSET_BITS=64 define to fuse.h. Note, that this is + an incompatible interface change. + +2002-10-28 Miklos Szeredi + + * Portablility fix (bug reported by C. Chris Erway) + +2002-10-25 Miklos Szeredi + + * Use Mark Glines' fd passing method for default operation instead + of old reexec + +2002-10-22 Miklos Szeredi + + * fix "Stale NFS file handle" bug caused by changes in 2.4.19 + +2002-10-22 Miklos Szeredi + + * fix incompatiblity with Red Hat kernels, with help from Nathan + Thompson-Amato. + +2002-04-18 Mark Glines + + * added an alternative to fuse_mount(), called + fuse_mount_ioslave(), which does not need to reexec the + FUSE program. + * added a small helper util needed by fuse_mount_ioslave(). + +2002-03-16 Mark Glines + + * use struct fuse_statfs everywhere possible to avoid problems + with the headerfiles changing struct statfs member sizes + +2002-03-01 Miklos Szeredi + + * Another RPM spec file for RedHat >= 7 by Ian Pilcher + +2002-01-14 Miklos Szeredi + + * RPM support by Achim Settelmeier + +2002-01-09 Miklos Szeredi + + * Version 0.95 released + +2002-01-09 Miklos Szeredi + + * Revaidate all path components not just the last, this means a + very small performance penalty for being more up-to-date. + +2002-01-08 Miklos Szeredi + + * Update and fix python interface + +2002-01-07 Mark Glines + + * Added statfs() support to kernel, lib, examples, and perl! + +2001-12-26 Miklos Szeredi + + * Better cross compilation support + + * Ported to Compaq IPAQ + +2001-12-20 Miklos Szeredi + + * Added function fuse_get_context() to library API (inspired by + patch from Matt Ryan) + + * Added flags to fusermount and to kernel interface to control + permission checking + + * Integrated fuse_set_operations() into fuse_new() + +2001-12-08 Miklos Szeredi + + * Applied header protection + extern "C" patch by Roland + Bauerschmidt + +2001-12-02 Miklos Szeredi + + * Added perl bindings by Mark Glines + +2001-11-21 Miklos Szeredi + + * Cleaned up way of mounting simple filesystems. + + * fuse_main() helper function added + +2001-11-18 Miklos Szeredi + + * Optimized read/write operations, so that minimal copying of data + is done + +2001-11-14 Miklos Szeredi + + * Python bindings by Jeff Epler added + +2001-11-13 Miklos Szeredi + + * Fixed vfsmount reference leak in fuse_follow_link + + * FS blocksize is set to PAGE_CACHE_SIZE, blksize attribute from + userspace is ignored + +2001-11-09 Miklos Szeredi + + * Started ChangeLog diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..691b1bc --- /dev/null +++ b/Makefile.am @@ -0,0 +1,15 @@ +## Process this file with automake to produce Makefile.in + +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = @subdirs2@ doc +AUTOMAKE_OPTIONS = subdir-objects + +EXTRA_DIST = \ + fuse.pc.in \ + README* + +pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = fuse.pc + +$(pkgconfig_DATA): config.status diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..95cd2c4 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,871 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = fuse.pc +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/fuse.pc.in AUTHORS \ + COPYING COPYING.LIB ChangeLog NEWS compile config.guess \ + config.rpath config.sub install-sh ltmain.sh missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INIT_D_PATH = @INIT_D_PATH@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MOUNT_FUSE_PATH = @MOUNT_FUSE_PATH@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UDEV_RULES_PATH = @UDEV_RULES_PATH@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libfuse_libs = @libfuse_libs@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs2 = @subdirs2@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = @subdirs2@ doc +AUTOMAKE_OPTIONS = subdir-objects +EXTRA_DIST = \ + fuse.pc.in \ + README* + +pkgconfig_DATA = fuse.pc +all: all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +fuse.pc: $(top_builddir)/config.status $(srcdir)/fuse.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgconfigDATA + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pkgconfigDATA install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + + +$(pkgconfig_DATA): config.status + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..559ee86 --- /dev/null +++ b/NEWS @@ -0,0 +1,303 @@ +What is new in 2.9 + + - Add "zero copy" support for kernel 2.6.35 or newer + + - Make maximum background requests tunable on kernel 2.6.32 or newer + + - Require --no-canonicalize in (u)mount (util-linux version 2.18 or + newer) to fix security problems with fusermount + + - Use dynamically sized hash tables in high level library + + - Memory use of filesystem daemon can shrink more easily + + - Add "auto_unmount" option + + - Add "remember" option + + - Add man pages for fusermount, mount.fuse and ulockmgr_server + + - API changes: + + o Introduce "store" and "retrieve" for accessing kernel buffers on + kernel 2.6.36 or newer + + o Introduce abstract buffer for zero copy operations + + o Allow path calculation to be omitted on certain operations + + o Allow batching forget requests + + o Add "flock" method + + o Add support for ioctl on directories + + o Add delete notification + + o Add fallocate operation (linux kernel 3.5 or newer) + + - Bug fixes and small improvements + +============================================================================ + +What is new in 2.8 + + - More scalable directory tree locking + + - Atomic open(O_TRUNC) support + + - Support big write requests on kernels 2.6.26 and newer + + - Out-of-tree fuse module removed + + - Better NFS exporting support + + - New ioctl and poll requests + + - New CUSE (Character Device in Userspace) interface + + - Allow umask processing in userspace + + - Added cache invalidation notifications + + - Bugfixes and small improvements + +============================================================================ + +What is new in 2.7 + + - Stacking support for the high level API + + - Add filename charset conversion module + + - Improved mounting + +============================================================================ + +What is new in 2.6 + + - Improved read characteristics (asynchronous reads) + + - Support for aborting filesystem connection + + - POSIX file locking support + + - Request interruption support + + - Building module for Linux kernels earlier than 2.6.9 not supported + + - Allow block device based filesystems to support swap files + + - Several bugs fixed, including a rare system hang on SMP + +============================================================================ + +What is new in 2.5 + + - Merge library part of FreeBSD port + + - New atomic create+open, access and ftruncate operations + + - On filesystems implementing the new create+open operation, and + running on Linux kernels 2.6.15 or later, the 'cp' operation will + work correctly when copying read-only files. + + - New option parsing interface added to the library + + - Lots of minor improvements and fixes + +============================================================================ + +What is new in 2.4 + + - Simplify device opening. Now '/dev/fuse' is a requirement + + - Allow module auto-loading if user has access to '/dev/fuse' + + - Allow mounting over a regular file for unprivileged users + + - Allow mounting of arbitrary FUSE filesystems from /etc/fstab + + - New mount options: 'umask=M', 'uid=N', 'gid=N' + + - Check for non-empty mountpoint, and refuse mount by default. New + mount option: 'nonempty' + + - Low level (inode based) API added + + - Allow 'direct_io' and 'keep_cache' options to be set on a + case-by-case basis on open. + + - Add 'attr_timeout' and 'entry_timeout' mount options to the + high-level library. Until now these timeouts were fixed at 1 sec. + + - Some bugfixes + +============================================================================ + +What is new in 2.3 + + - Add new directory related operations: opendir(), readdir(), + releasedir() and fsyncdir() + + - Add init() and destroy() operations which are called before the + event loop is started and after it has exited + + - Update kernel ABI so that on dual architectures (e.g. AMD64) 32bit + binaries work under a 64bit kernel + + - Bugfixes + +============================================================================ + +What is new in 2.2 + +Userspace changes: + + - Add fuse_file_info structure to file operations, this allows the + filesystem to return a file handle in open() which is passed to + read(), write(), flush(), fsync() and release(). + + - Add source compatibility with 2.1 and 1.4 releases + + - Binary compatibility with 2.1 release is retained + +Kernel changes: + + - Make requests interruptible. This prevents the filesystem to go + into an unbreakable deadlock with itself. + + - Make readpages() synchronous. Asynchronous requests are deadlock + prone, since they cannot be interrupted (see above) + + - Remove shared-writeable mapping support, which could deadlock the + machine + + - Remove INVALIDATE userspace initiated request + + - Update ABI to be independent of sizeof(long), so dual-size archs + don't cause problems + + - Remove /sys/fs/fuse/version. Version checking is now done through + the fuse device + + - Replace directory reading method on the kernel interface. Instead + of passing an open file descriptor to the kernel, send data through + the FUSE device, like all other operations. + +============================================================================ + +What is new in 2.1 + +* Bug fixes + +* Improved support for filesystems implementing a custom event-loop + +* Add 'pkg-config' support + +* Kernel module can be compiled separately + +============================================================================ + +What is new in 1.9 + +* Lots of bugs fixed + +* Minor modifications to the library API + +* Improvements to the kernel/userspace interface + +* Mounting by non-root made more secure + +* Build shared library in addition to the static one + +* Consolidated mount options + +* Optimized reading under 2.6 kernels + +* Direct I/O support + +* Support file I/O on deleted files + +* Extended attributes support + +============================================================================ + +What is new in 1.3 + +* Thanks to user bugreports and stress testing with LTP and sfx-linux +a number of bugs were fixed, some quite serious. + +* Fix compile problems with recent SuSE kernles + +============================================================================ + +What is new in 1.2 + +* Fix mount problems on recent 2.6 kernels with SELinux enabled + +* Fixed writing files lager than 2GBytes + +* Other bugfixes + +============================================================================ + +What is new in 1.1 + +* Support for the 2.6 kernels + +* Support for exporting filesystem over NFS in 2.6 kernels + +* Read efficiency improvements: read in 64k blocks instead of 4k +(Michael Grigoriev). Can be turned on with '-l' option of fusermount + +* Lazy automatic unmount + +* Added 'fsync()' VFS call to the FUSE interface + +* Bugfixes + +============================================================================ + +What is new in 1.0 + +* Cleanups and bugfixes + +* Added 'release()' VFS call to the FUSE interface + +* 64 bit file offsets (handling of > 4 GByte files) + +* libfuse is now under LGPL + +* New 'statfs' call (Mark Glines) + +* Cleaned up mount procedure (mostly by Mark Glines) + + NOTE: Binaries linked with with a previous version of libavfs may + not work with the new version of the fusermount program. In such + case recompile the program after installing the new libavfs library. + +* Fix for problems under linux kernel 2.4.19 + +============================================================================ + +What is new in 0.95 + +* Optimized read/write operations. Raw throughput has increased to +about 60Mbyte/s on a Celeron/360 + +* Python bindings by Jeff Epler + +* Perl bindings by Mark Glines + +* Improved multithreaded operation + +* Simplified library interface + +* Bugfixes + +============================================================================ + +What is new in 0.9: + +* Everything diff --git a/README.NFS b/README.NFS new file mode 100644 index 0000000..f3348d5 --- /dev/null +++ b/README.NFS @@ -0,0 +1,33 @@ +NFS exporting is supported in Linux kernels 2.6.27 or later. + +You need to add an fsid=NNN option to /etc/exports to make exporting a +FUSE directory work. + +Filesystem support +------------------ + +NFS exporting works to some extent on all fuse filesystems, but not +perfectly. This is due to the stateless nature of the protocol, the +server has no way of knowing whether the client is keeping a reference +to a file or not, and hence that file may be removed from the server's +cache. In that case there has to be a way to look up that object +using the inode number, otherwise an ESTALE error will be returned. + +1) low-level interface + +Filesystems need to implement special lookups for the names "." and +"..". The former may be requested on any inode, including +non-directories, while the latter is only requested for directories. +Otherwise these special lookups should behave identically to ordinary +lookups. + +2) high-level interface + +Because the high-level interface is path based, it is not possible to +delegate looking up by inode to the filesystem. + +To work around this, currently a "noforget" option is provided, which +makes the library remember nodes forever. This will make the NFS +server happy, but also results in an ever growing memory footprint for +the filesystem. For this reason if the filesystem is large (or the +memory is small), then this option is not recommended. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2243a12 --- /dev/null +++ b/README.md @@ -0,0 +1,108 @@ +libfuse +======= + +Warning: unresolved security issue +---------------------------------- + +Be aware that FUSE has an unresolved security bug +([bug #15](https://github.com/libfuse/libfuse/issues/15)): the +permission check for accessing a cached directory is only done once +when the directory entry is first loaded into the cache. Subsequent +accesses will re-use the results of the first check, even if the +directory permissions have since changed, and even if the subsequent +access is made by a different user. + +This bug needs to be fixed in the Linux kernel and has been known +since 2006 but unfortunately no fix has been applied yet. If you +depend on correct permission handling for FUSE file systems, the only +workaround is to completely disable caching of directory +entries. Alternatively, the severity of the bug can be somewhat +reduced by not using the `allow_other` mount option. + + +About +----- + +FUSE (Filesystem in Userspace) is an interface for userspace programs +to export a filesystem to the Linux kernel. The FUSE project consists +of two components: the *fuse* kernel module (maintained in the regular +kernel repositories) and the *libfuse* userspace library (maintained +in this repository). libfuse provides the reference implementation +for communicating with the FUSE kernel module. + +A FUSE file system is typically implemented as a standalone +application that links with libfuse. libfuse provides functions to +mount the file system, unmount it, read requests from the kernel, and +send responses back. libfuse offers two APIs: a "high-level", +synchronous API, and a "low-level" asynchronous API. In both cases, +incoming requests from the kernel are passed to the main program using +callbacks. When using the high-level API, the callbacks may work with +file names and paths instead of inodes, and processing of a request +finishes when the callback function returns. When using the low-level +API, the callbacks must work with inodes and responses must be sent +explicitly using a separate set of API functions. + + +Installation +------------ + + ./configure + make -j8 + make install + +You may also need to add `/usr/local/lib` to `/etc/ld.so.conf` and/or +run *ldconfig*. If you're building from the git repository (instead of +using a release tarball), you also need to run `./makeconf.sh` to +create the `configure` script. + +You'll also need a fuse kernel module (Linux kernels 2.6.14 or later +contain FUSE support). + +For more details see the file `INSTALL` + +Security implications +--------------------- + +If you run `make install`, the *fusermount* program is installed +set-user-id to root. This is done to allow normal users to mount +their own filesystem implementations. + +There must however be some limitations, in order to prevent Bad User from +doing nasty things. Currently those limitations are: + + - The user can only mount on a mountpoint, for which it has write + permission + + - The mountpoint is not a sticky directory which isn't owned by the + user (like /tmp usually is) + + - No other user (including root) can access the contents of the + mounted filesystem (though this can be relaxed by allowing the use + of the `allow_other` and `allow_root` mount options in `fuse.conf`) + + +Building your own filesystem +------------------------------ + +FUSE comes with several example file systems in the `examples` +directory. For example, the *fusexmp* example mirrors the contents of +the root directory under the mountpoint. Start from there and adapt +the code! + +The documentation of the API functions and necessary callbacks is +mostly contained in the files `include/fuse.h` (for the high-level +API) and `include/fuse_lowlevel.h` (for the low-level API). An +autogenerated html version of the API is available in the `doc/html` +directory and at http://libfuse.github.io/doxygen. + + +Getting Help +------------ + +If you need help, please ask on the +mailing list (subscribe at +https://lists.sourceforge.net/lists/listinfo/fuse-devel). + +Please report any bugs on the GitHub issue tracker at +https://github.com/libfuse/main/issues. + diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..8f8b465 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,2552 @@ +# generated automatically by aclocal 1.15 -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# iconv.m4 serial 19 (gettext-0.18.2) +dnl Copyright (C) 2000-2002, 2007-2014, 2016 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + ]], + [[iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);]])], + [am_cv_func_iconv=yes]) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + ]], + [[iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);]])], + [am_cv_lib_iconv=yes] + [am_cv_func_iconv=yes]) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ + dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, + dnl Solaris 10. + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + am_cv_func_iconv_works=no + for ac_iconv_const in '' 'const'; do + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + +#ifndef ICONV_CONST +# define ICONV_CONST $ac_iconv_const +#endif + ]], + [[int result = 0; + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 1; + iconv_close (cd_utf8_to_88591); + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\263"; + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 2; + iconv_close (cd_ascii_to_88591); + } + } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304"; + static char buf[2] = { (char)0xDE, (char)0xAD }; + ICONV_CONST char *inptr = input; + size_t inbytesleft = 1; + char *outptr = buf; + size_t outbytesleft = 1; + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) + result |= 4; + iconv_close (cd_88591_to_utf8); + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + result |= 8; + iconv_close (cd_88591_to_utf8); + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + if (/* Try standardized names. */ + iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) + /* Try IRIX, OSF/1 names. */ + && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) + /* Try AIX names. */ + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) + result |= 16; + return result; +]])], + [am_cv_func_iconv_works=yes], , + [case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac]) + test "$am_cv_func_iconv_works" = no || break + done + LIBS="$am_save_LIBS" + ]) + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + AC_DEFINE([HAVE_ICONV], [1], + [Define if you have the iconv() function and it works.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST([LIBICONV]) + AC_SUBST([LTLIBICONV]) +]) + +dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to +dnl avoid warnings like +dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". +dnl This is tricky because of the way 'aclocal' is implemented: +dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. +dnl Otherwise aclocal's initial scan pass would miss the macro definition. +dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. +dnl Otherwise aclocal would emit many "Use of uninitialized value $1" +dnl warnings. +m4_define([gl_iconv_AC_DEFUN], + m4_version_prereq([2.64], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [m4_ifdef([gl_00GNULIB], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [[AC_DEFUN( + [$1], [$2])]])])) +gl_iconv_AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL([am_cv_proto_iconv], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif + ]], + [[]])], + [am_cv_proto_iconv_arg1=""], + [am_cv_proto_iconv_arg1="const"]) + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([ + $am_cv_proto_iconv]) + AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], + [Define as const if the declaration of iconv() needs const.]) + dnl Also substitute ICONV_CONST in the gnulib generated . + m4_ifdef([gl_ICONV_H_DEFAULTS], + [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + if test -n "$am_cv_proto_iconv_arg1"; then + ICONV_CONST="const" + fi + ]) + fi +]) + +# lib-ld.m4 serial 6 +dnl Copyright (C) 1996-2003, 2009-2016 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid +dnl collision with libtool.m4. + +dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 /dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` + while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL([acl_cv_path_LD], +[if test -z "$LD"; then + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 = 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE([rpath], + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_FROMPACKAGE(name, package) +dnl declares that libname comes from the given package. The configure file +dnl will then not have a --with-libname-prefix option but a +dnl --with-package-prefix option. Several libraries can come from the same +dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar +dnl macro call that searches for libname. +AC_DEFUN([AC_LIB_FROMPACKAGE], +[ + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) + popdef([PACKUP]) + popdef([PACK]) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found +dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) + dnl Autoconf >= 2.61 supports dots in --with options. + pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH(P_A_C_K[-prefix], +[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib + --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && ! test -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + LIB[]NAME[]_PREFIX= + dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been + dnl computed. So it has to be reset here. + HAVE_LIB[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$acl_hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi + popdef([P_A_C_K]) + popdef([PACKLIBS]) + popdef([PACKUP]) + popdef([PACK]) + popdef([NAME]) +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) + +# lib-prefix.m4 serial 7 (gettext-0.18) +dnl Copyright (C) 2001-2005, 2008-2016 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a variable acl_libdirstem, containing the basename of the libdir, either +dnl "lib" or "lib64" or "lib/64", +dnl - a variable acl_libdirstem2, as a secondary possible value for +dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or +dnl "lib/amd64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. + dnl On glibc systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine + dnl the compiler's default mode by looking at the compiler's library search + dnl path. If at least one of its elements ends in /lib64 or points to a + dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. + dnl Otherwise we use the default, namely "lib". + dnl On Solaris systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or + dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. + AC_REQUIRE([AC_CANONICAL_HOST]) + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl . + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], + [AC_EGREP_CPP([sixtyfour bits], [ +#ifdef _LP64 +sixtyfour bits +#endif + ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) + ]) + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" +]) + +# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) diff --git a/compile b/compile new file mode 100755 index 0000000..a85b723 --- /dev/null +++ b/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..2e9ad7f --- /dev/null +++ b/config.guess @@ -0,0 +1,1462 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2016 Free Software Foundation, Inc. + +timestamp='2016-10-02' + +# 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 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 . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2016 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "${UNAME_MACHINE_ARCH}" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = hppa2.0w ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + *:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + k1om:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + mips64el:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; +esac + +cat >&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.rpath b/config.rpath new file mode 100755 index 0000000..98183ff --- /dev/null +++ b/config.rpath @@ -0,0 +1,684 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2016 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + nagfor*) + wl='-Wl,-Wl,,' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + xl* | bgxl* | bgf* | mpixl*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + wl= + ;; + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + newsos6) + ;; + *nto* | *qnx*) + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + rdos*) + ;; + solaris*) + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + wl='-Qoption ld ' + ;; + *) + wl='-Wl,' + ;; + esac + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32* | cegcc*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + haiku*) + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then + : + else + ld_shlibs=no + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd2.[01]*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + *nto* | *qnx*) + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +# Unlike libtool.m4, here we don't care about _all_ names of the library, but +# only about the one the linker finds when passed -lNAME. This is the last +# element of library_names_spec in libtool.m4, or possibly two of them if the +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 +libname_spec='lib$name' +case "$host_os" in + aix3*) + library_names_spec='$libname.a' + ;; + aix[4-9]*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + case "$host_cpu" in + powerpc*) + library_names_spec='$libname$shrext' ;; + m68k) + library_names_spec='$libname.a' ;; + esac + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib + library_names_spec='$libname$shrext' + ;; + dgux*) + library_names_spec='$libname$shrext' + ;; + freebsd[23].*) + library_names_spec='$libname$shrext$versuffix' + ;; + freebsd* | dragonfly*) + library_names_spec='$libname$shrext' + ;; + gnu*) + library_names_spec='$libname$shrext' + ;; + haiku*) + library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' + ;; + netbsd*) + library_names_spec='$libname$shrext' + ;; + newsos6) + library_names_spec='$libname$shrext' + ;; + *nto* | *qnx*) + library_names_spec='$libname$shrext' + ;; + openbsd*) + library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll + library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' + ;; + rdos*) + ;; + solaris*) + library_names_spec='$libname$shrext' + ;; + sunos4*) + library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' + ;; + sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + tpf*) + library_names_spec='$libname$shrext' + ;; + uts4*) + library_names_spec='$libname$shrext' + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2016 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -ios) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..47df8b3 --- /dev/null +++ b/configure @@ -0,0 +1,16407 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for fuse 2.9.9. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='fuse' +PACKAGE_TARNAME='fuse' +PACKAGE_VERSION='2.9.9' +PACKAGE_STRING='fuse 2.9.9' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +BSD_FALSE +BSD_TRUE +NETBSD_FALSE +NETBSD_TRUE +LINUX_FALSE +LINUX_TRUE +subdirs2 +INIT_D_PATH +UDEV_RULES_PATH +MOUNT_FUSE_PATH +libfuse_libs +ICONV_FALSE +ICONV_TRUE +LTLIBICONV +LIBICONV +pkgconfigdir +CPP +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +LIBTOOL +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +enable_dependency_tracking +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_lib +enable_util +enable_example +enable_mtab +with_pkgconfigdir +with_libiconv_prefix +enable_rpath +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +LT_SYS_LIBRARY_PATH +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures fuse 2.9.9 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/fuse] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of fuse 2.9.9:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-lib Compile with library + --enable-util Compile with util + --enable-example Compile with examples + --disable-mtab Disable and ignore usage of /etc/mtab + --disable-rpath do not hardcode runtime library paths + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-pkgconfigdir=DIR pkgconfig file in DIR [LIBDIR/pkgconfig] + --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib + --without-libiconv-prefix don't search for libiconv in includedir and libdir + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +fuse configure 2.9.9 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by fuse $as_me 2.9.9, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- +am__api_version='1.15' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='fuse' + VERSION='2.9.9' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +ac_config_headers="$ac_config_headers include/config.h" + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + + + +case $target_os in + *linux*) arch=linux;; + *netbsd*) arch=netbsd;; + *bsd*) arch=bsd;; + *) arch=unknown;; +esac + +if test "$ac_env_CFLAGS_set" != set; then + CFLAGS="-Wall -W -Wno-sign-compare -Wstrict-prototypes -Wmissing-declarations -Wwrite-strings -g -O2 -fno-strict-aliasing" +fi + +# Check whether --enable-lib was given. +if test "${enable_lib+set}" = set; then : + enableval=$enable_lib; +fi + +# Check whether --enable-util was given. +if test "${enable_util+set}" = set; then : + enableval=$enable_util; +fi + +# Check whether --enable-example was given. +if test "${enable_example+set}" = set; then : + enableval=$enable_example; +fi + +# Check whether --enable-mtab was given. +if test "${enable_mtab+set}" = set; then : + enableval=$enable_mtab; +fi + + + +# Check whether --with-pkgconfigdir was given. +if test "${with_pkgconfigdir+set}" = set; then : + withval=$with_pkgconfigdir; pkgconfigdir=$withval +else + pkgconfigdir='${libdir}/pkgconfig' +fi + + + +subdirs2="include" + +if test "$enable_lib" != "no"; then + subdirs2="$subdirs2 lib"; +fi +if test "$arch" = linux -a "$enable_util" != "no"; then + subdirs2="$subdirs2 util"; +fi +if test "$enable_example" != "no"; then + subdirs2="$subdirs2 example"; +fi +if test "$enable_mtab" = "no"; then + +$as_echo "#define IGNORE_MTAB 1" >>confdefs.h + +fi + +for ac_func in fork setxattr fdatasync splice vmsplice utimensat +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in posix_fallocate +do : + ac_fn_c_check_func "$LINENO" "posix_fallocate" "ac_cv_func_posix_fallocate" +if test "x$ac_cv_func_posix_fallocate" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_POSIX_FALLOCATE 1 +_ACEOF + +fi +done + +ac_fn_c_check_member "$LINENO" "struct stat" "st_atim" "ac_cv_member_struct_stat_st_atim" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_atim" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_ATIM 1 +_ACEOF + + +fi + +ac_fn_c_check_member "$LINENO" "struct stat" "st_atimespec" "ac_cv_member_struct_stat_st_atimespec" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_atimespec" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_ATIMESPEC 1 +_ACEOF + + +fi + + +LIBS= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 +$as_echo_n "checking for library containing dlopen... " >&6; } +if ${ac_cv_search_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dlopen=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dlopen+:} false; then : + break +fi +done +if ${ac_cv_search_dlopen+:} false; then : + +else + ac_cv_search_dlopen=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 +$as_echo "$ac_cv_search_dlopen" >&6; } +ac_res=$ac_cv_search_dlopen +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 +$as_echo_n "checking for library containing clock_gettime... " >&6; } +if ${ac_cv_search_clock_gettime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_clock_gettime=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_clock_gettime+:} false; then : + break +fi +done +if ${ac_cv_search_clock_gettime+:} false; then : + +else + ac_cv_search_clock_gettime=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 +$as_echo "$ac_cv_search_clock_gettime" >&6; } +ac_res=$ac_cv_search_clock_gettime +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +libfuse_libs=$LIBS +LIBS= + +# Check whether --with-libiconv-prefix was given. +if test "${with_libiconv_prefix+set}" = set; then : + withval=$with_libiconv_prefix; + for dir in `echo "$withval" | tr : ' '`; do + if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi + if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi + done + +fi + + + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` + while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${acl_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${acl_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$acl_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +$as_echo_n "checking for shared library run path origin... " >&6; } +if ${acl_cv_rpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +$as_echo "$acl_cv_rpath" >&6; } + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; : +else + enable_rpath=yes +fi + + + + + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 +$as_echo_n "checking for 64-bit host... " >&6; } +if ${gl_cv_solaris_64bit+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef _LP64 +sixtyfour bits +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "sixtyfour bits" >/dev/null 2>&1; then : + gl_cv_solaris_64bit=yes +else + gl_cv_solaris_64bit=no +fi +rm -f conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5 +$as_echo "$gl_cv_solaris_64bit" >&6; } + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + + + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libiconv-prefix was given. +if test "${with_libiconv_prefix+set}" = set; then : + withval=$with_libiconv_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && ! test -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi + +fi + + LIBICONV= + LTLIBICONV= + INCICONV= + LIBICONV_PREFIX= + HAVE_LIBICONV= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='iconv ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$acl_hardcode_direct" = yes; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" + ;; + esac + done + fi + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" + done + fi + + + + + + + + + + + + + am_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCICONV; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +$as_echo_n "checking for iconv... " >&6; } +if ${am_cv_func_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$am_save_LIBS" + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 +$as_echo "$am_cv_func_iconv" >&6; } + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 +$as_echo_n "checking for working iconv... " >&6; } +if ${am_cv_func_iconv_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + am_cv_func_iconv_works=no + for ac_iconv_const in '' 'const'; do + if test "$cross_compiling" = yes; then : + case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +#ifndef ICONV_CONST +# define ICONV_CONST $ac_iconv_const +#endif + +int +main () +{ +int result = 0; + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 1; + iconv_close (cd_utf8_to_88591); + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\263"; + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 2; + iconv_close (cd_ascii_to_88591); + } + } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304"; + static char buf[2] = { (char)0xDE, (char)0xAD }; + ICONV_CONST char *inptr = input; + size_t inbytesleft = 1; + char *outptr = buf; + size_t outbytesleft = 1; + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) + result |= 4; + iconv_close (cd_88591_to_utf8); + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + result |= 8; + iconv_close (cd_88591_to_utf8); + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + if (/* Try standardized names. */ + iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) + /* Try IRIX, OSF/1 names. */ + && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) + /* Try AIX names. */ + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) + result |= 16; + return result; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + am_cv_func_iconv_works=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + test "$am_cv_func_iconv_works" = no || break + done + LIBS="$am_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 +$as_echo "$am_cv_func_iconv_works" >&6; } + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + +$as_echo "#define HAVE_ICONV 1" >>confdefs.h + + fi + if test "$am_cv_lib_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 +$as_echo_n "checking how to link with libiconv... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 +$as_echo "$LIBICONV" >&6; } + else + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + + + + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 +$as_echo_n "checking for iconv declaration... " >&6; } + if ${am_cv_proto_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + am_cv_proto_iconv_arg1="" +else + am_cv_proto_iconv_arg1="const" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" +fi + + am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: + $am_cv_proto_iconv" >&5 +$as_echo " + $am_cv_proto_iconv" >&6; } + +cat >>confdefs.h <<_ACEOF +#define ICONV_CONST $am_cv_proto_iconv_arg1 +_ACEOF + + + fi + +libfuse_libs="$libfuse_libs $LTLIBICONV" + if test "$am_cv_func_iconv" = yes; then + ICONV_TRUE= + ICONV_FALSE='#' +else + ICONV_TRUE='#' + ICONV_FALSE= +fi + + + +if test -z "$MOUNT_FUSE_PATH"; then + MOUNT_FUSE_PATH=/sbin + { $as_echo "$as_me:${as_lineno-$LINENO}: MOUNT_FUSE_PATH env var not set, using default $MOUNT_FUSE_PATH" >&5 +$as_echo "$as_me: MOUNT_FUSE_PATH env var not set, using default $MOUNT_FUSE_PATH" >&6;} +fi + +if test -z "$UDEV_RULES_PATH"; then + UDEV_RULES_PATH=/etc/udev/rules.d + { $as_echo "$as_me:${as_lineno-$LINENO}: UDEV_RULES_PATH env var not set, using default $UDEV_RULES_PATH" >&5 +$as_echo "$as_me: UDEV_RULES_PATH env var not set, using default $UDEV_RULES_PATH" >&6;} +fi + +if test -z "$INIT_D_PATH"; then + INIT_D_PATH=/etc/init.d + { $as_echo "$as_me:${as_lineno-$LINENO}: INIT_D_PATH env var not set, using default $INIT_D_PATH" >&5 +$as_echo "$as_me: INIT_D_PATH env var not set, using default $INIT_D_PATH" >&6;} +fi + + + + + if test "$arch" = linux; then + LINUX_TRUE= + LINUX_FALSE='#' +else + LINUX_TRUE='#' + LINUX_FALSE= +fi + + if test "$arch" = netbsd; then + NETBSD_TRUE= + NETBSD_FALSE='#' +else + NETBSD_TRUE='#' + NETBSD_FALSE= +fi + + if test "$arch" = bsd; then + BSD_TRUE= + BSD_FALSE='#' +else + BSD_TRUE='#' + BSD_FALSE= +fi + + +util_linux_ok=yes +if test "$arch" = linux -a "$cross_compiling" != "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if umount supports --fake --no-canonicalize" >&5 +$as_echo_n "checking if umount supports --fake --no-canonicalize... " >&6; } + # exit code of umount is 1 if option is unrecognised, 2 otherwise + umount --fake --no-canonicalize > /dev/null 2>&1 + if test $? != 1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + firstline=`umount --fake --no-canonicalize 2>&1 | head -1` + if test "$firstline" = 'umount: only root can use "--fake" option'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $firstline" >&5 +$as_echo "$firstline" >&6; } + util_linux_ok=no + fi + fi +fi + +ac_config_files="$ac_config_files fuse.pc Makefile lib/Makefile util/Makefile example/Makefile include/Makefile doc/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ICONV_TRUE}" && test -z "${ICONV_FALSE}"; then + as_fn_error $? "conditional \"ICONV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then + as_fn_error $? "conditional \"LINUX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${NETBSD_TRUE}" && test -z "${NETBSD_FALSE}"; then + as_fn_error $? "conditional \"NETBSD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BSD_TRUE}" && test -z "${BSD_FALSE}"; then + as_fn_error $? "conditional \"BSD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by fuse $as_me 2.9.9, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +fuse config.status 2.9.9 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "fuse.pc") CONFIG_FILES="$CONFIG_FILES fuse.pc" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; + "util/Makefile") CONFIG_FILES="$CONFIG_FILES util/Makefile" ;; + "example/Makefile") CONFIG_FILES="$CONFIG_FILES example/Makefile" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 . + + +# The names of the tagged configurations supported by this script. +available_tags='' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +if test "$util_linux_ok" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +****************************************************************** +* Please install util-linux version 2.18 or later which supports * +* --fake and --no-canonicalize options in mount and umount * +******************************************************************" >&5 +$as_echo "$as_me: WARNING: +****************************************************************** +* Please install util-linux version 2.18 or later which supports * +* --fake and --no-canonicalize options in mount and umount * +******************************************************************" >&2;} +fi diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..9946a0e --- /dev/null +++ b/configure.ac @@ -0,0 +1,127 @@ +AC_INIT(fuse, 2.9.9) + +AC_PREREQ(2.59d) +AC_CONFIG_MACRO_DIR([m4]) +AC_CANONICAL_TARGET +AM_INIT_AUTOMAKE([foreign]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)]) +AC_CONFIG_HEADERS(include/config.h) + +AC_PROG_LIBTOOL +AC_PROG_CC +AC_PROG_MKDIR_P +AM_PROG_CC_C_O + +case $target_os in + *linux*) arch=linux;; + *netbsd*) arch=netbsd;; + *bsd*) arch=bsd;; + *) arch=unknown;; +esac + +if test "$ac_env_CFLAGS_set" != set; then + CFLAGS="-Wall -W -Wno-sign-compare -Wstrict-prototypes -Wmissing-declarations -Wwrite-strings -g -O2 -fno-strict-aliasing" +fi + +AC_ARG_ENABLE(lib, + [ --enable-lib Compile with library ]) +AC_ARG_ENABLE(util, + [ --enable-util Compile with util ]) +AC_ARG_ENABLE(example, + [ --enable-example Compile with examples ]) +AC_ARG_ENABLE(mtab, + [ --disable-mtab Disable and ignore usage of /etc/mtab ]) + +AC_ARG_WITH(pkgconfigdir, + [ --with-pkgconfigdir=DIR pkgconfig file in DIR @<:@LIBDIR/pkgconfig@:>@], + [pkgconfigdir=$withval], + [pkgconfigdir='${libdir}/pkgconfig']) +AC_SUBST(pkgconfigdir) + +subdirs2="include" + +if test "$enable_lib" != "no"; then + subdirs2="$subdirs2 lib"; +fi +if test "$arch" = linux -a "$enable_util" != "no"; then + subdirs2="$subdirs2 util"; +fi +if test "$enable_example" != "no"; then + subdirs2="$subdirs2 example"; +fi +if test "$enable_mtab" = "no"; then + AC_DEFINE(IGNORE_MTAB, 1, [Don't update /etc/mtab]) +fi + +AC_CHECK_FUNCS([fork setxattr fdatasync splice vmsplice utimensat]) +AC_CHECK_FUNCS([posix_fallocate]) +AC_CHECK_MEMBERS([struct stat.st_atim]) +AC_CHECK_MEMBERS([struct stat.st_atimespec]) + +LIBS= +AC_SEARCH_LIBS(dlopen, [dl]) +AC_SEARCH_LIBS(clock_gettime, [rt]) +libfuse_libs=$LIBS +LIBS= +AC_ARG_WITH([libiconv-prefix], +[ --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib], [ + for dir in `echo "$withval" | tr : ' '`; do + if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi + if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi + done + ]) +AM_ICONV +libfuse_libs="$libfuse_libs $LTLIBICONV" +AM_CONDITIONAL(ICONV, test "$am_cv_func_iconv" = yes) +AC_SUBST(libfuse_libs) + +if test -z "$MOUNT_FUSE_PATH"; then + MOUNT_FUSE_PATH=/sbin + AC_MSG_NOTICE([MOUNT_FUSE_PATH env var not set, using default $MOUNT_FUSE_PATH]) +fi +AC_SUBST(MOUNT_FUSE_PATH) +if test -z "$UDEV_RULES_PATH"; then + UDEV_RULES_PATH=/etc/udev/rules.d + AC_MSG_NOTICE([UDEV_RULES_PATH env var not set, using default $UDEV_RULES_PATH]) +fi +AC_SUBST(UDEV_RULES_PATH) +if test -z "$INIT_D_PATH"; then + INIT_D_PATH=/etc/init.d + AC_MSG_NOTICE([INIT_D_PATH env var not set, using default $INIT_D_PATH]) +fi +AC_SUBST(INIT_D_PATH) + +AC_SUBST(subdirs2) + +AM_CONDITIONAL(LINUX, test "$arch" = linux) +AM_CONDITIONAL(NETBSD, test "$arch" = netbsd) +AM_CONDITIONAL(BSD, test "$arch" = bsd) + +util_linux_ok=yes +if test "$arch" = linux -a "$cross_compiling" != "yes"; then + AC_MSG_CHECKING([if umount supports --fake --no-canonicalize]) + # exit code of umount is 1 if option is unrecognised, 2 otherwise + umount --fake --no-canonicalize > /dev/null 2>&1 + if test $? != 1; then + AC_MSG_RESULT([yes]) + else + firstline=`umount --fake --no-canonicalize 2>&1 | head -1` + if test "$firstline" = 'umount: only root can use "--fake" option'; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([$firstline]) + util_linux_ok=no + fi + fi +fi + +AC_CONFIG_FILES([fuse.pc Makefile lib/Makefile util/Makefile example/Makefile include/Makefile doc/Makefile]) +AC_OUTPUT + +if test "$util_linux_ok" = no; then + AC_MSG_WARN([ +****************************************************************** +* Please install util-linux version 2.18 or later which supports * +* --fake and --no-canonicalize options in mount and umount * +******************************************************************]) +fi diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..fc98710 --- /dev/null +++ b/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2013-05-30.07; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/doc/Doxyfile b/doc/Doxyfile new file mode 100644 index 0000000..3926aaf --- /dev/null +++ b/doc/Doxyfile @@ -0,0 +1,1427 @@ +# Doxyfile 1.5.6 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = fuse + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = include + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to FRAME, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. Other possible values +# for this tag are: HIERARCHIES, which will generate the Groups, Directories, +# and Class Hiererachy pages using a tree view instead of an ordered list; +# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which +# disables this behavior completely. For backwards compatibility with previous +# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE +# respectively. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 1000 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is enabled by default, which results in a transparent +# background. Warning: Depending on the platform used, enabling this option +# may lead to badly anti-aliased labels on the edges of a graph (i.e. they +# become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..1d38e48 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,5 @@ +## Process this file with automake to produce Makefile.in + +dist_man_MANS = fusermount.1 mount.fuse.8 ulockmgr_server.1 + +EXTRA_DIST = how-fuse-works kernel.txt Doxyfile html diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..e92a308 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,574 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(dist_man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INIT_D_PATH = @INIT_D_PATH@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MOUNT_FUSE_PATH = @MOUNT_FUSE_PATH@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UDEV_RULES_PATH = @UDEV_RULES_PATH@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libfuse_libs = @libfuse_libs@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs2 = @subdirs2@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +dist_man_MANS = fusermount.1 mount.fuse.8 ulockmgr_server.1 +EXTRA_DIST = how-fuse-works kernel.txt Doxyfile html +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(dist_man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-man8: $(dist_man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_man_MANS)'; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(MANS) +installdirs: + for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man + +uninstall-man: uninstall-man1 uninstall-man8 + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man1 install-man8 install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am uninstall-man uninstall-man1 uninstall-man8 + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/fusermount.1 b/doc/fusermount.1 new file mode 100644 index 0000000..86998e2 --- /dev/null +++ b/doc/fusermount.1 @@ -0,0 +1,39 @@ +.TH FUSERMOUNT 1 2011\-10\-23 2.8.6 "Filesystem in Userspace (FUSE)" + +.SH NAME +\fBfusermount\fR \- mount and unmount FUSE filesystems + +.SH SYNOPSIS +\fBfusermount\fR [\fIOPTIONS\fR] \fIMOUNTPOINT\fR + +.SH DESCRIPTION +Filesystem in Userspace (FUSE) is a simple interface for userspace programs to export a virtual filesystem to the Linux kernel. It also aims to provide a secure method for non privileged users to create and mount their own filesystem implementations. +.PP +\fBfusermount\fR is a program to mount and unmount FUSE filesystems. + +.SH OPTIONS +.IP "\-h" 4 +print help. +.IP "\-V" 4 +print version. +.IP "-o \fIOPTION\fR[,\fIOPTION\fR...]" 4 +mount options. +.IP "-u" 4 +unmount. +.IP "-q" 4 +quiet. +.IP "-z" 4 +lazy unmount. + +.SH SEE ALSO +\fImount\fR(8), +\fImount.fuse\fR(8), +\fIulockmgr_server\fR(1). + +.SH HOMEPAGE +More information about fusermount and the FUSE project can be found at <\fIhttp://fuse.sourceforge.net/\fR>. + +.SH AUTHOR +FUSE was written by Miklos Szeredi <\fImiklos@szeredi.hu\fR>. +.PP +This manual page was written by Daniel Baumann <\fIdaniel.baumann@progress\-technologies.net\fR>. diff --git a/doc/how-fuse-works b/doc/how-fuse-works new file mode 100644 index 0000000..a5febe3 --- /dev/null +++ b/doc/how-fuse-works @@ -0,0 +1,54 @@ + How Fuse-1.3 Works + +[Written by Terje Oseberg] + +1. The fuse library. + +When your user mode program calls fuse_main() (lib/helper.c), +fuse_main() parses the arguments passed to your user mode program, +then calls fuse_mount() (lib/mount.c). + +fuse_mount() creates a UNIX domain socket pair, then forks and execs +fusermount (util/fusermount.c) passing it one end of the socket in the +FUSE_COMMFD_ENV environment variable. + +fusermount (util/fusermount.c) makes sure that the fuse module is +loaded. fusermount then open /dev/fuse and send the file handle over a +UNIX domain socket back to fuse_mount(). + +fuse_mount() returns the filehandle for /dev/fuse to fuse_main(). + +fuse_main() calls fuse_new() (lib/fuse.c) which allocates the struct +fuse datastructure that stores and maintains a cached image of the +filesystem data. + +Lastly, fuse_main() calls either fuse_loop() (lib/fuse.c) or +fuse_loop_mt() (lib/fuse_mt.c) which both start to read the filesystem +system calls from the /dev/fuse, call the usermode functions +stored in struct fuse_operations datastructure before calling +fuse_main(). The results of those calls are then written back to the +/dev/fuse file where they can be forwarded back to the system +calls. + +2. The kernel module. + +The kernel module consists of two parts. First the proc filesystem +component in kernel/dev.c -and second the filesystem system calls +kernel/file.c, kernel/inode.c, and kernel/dir.c + +All the system calls in kernel/file.c, kernel/inode.c, and +kernel/dir.c make calls to either request_send(), +request_send_noreply(), or request_send_nonblock(). Most of the calls +(all but 2) are to request_send(). request_send() adds the request to, +"list of requests" structure (fc->pending), then waits for a response. +request_send_noreply() and request_send_nonblock() are both similar in +function to request_send() except that one is non-blocking, and the +other does not respond with a reply. + +The proc filesystem component in kernel/dev.c responds to file io +requests to the file /dev/fuse. fuse_dev_read() handles the +file reads and returns commands from the "list of requests" structure +to the calling program. fuse_dev_write() handles file writes and takes +the data written and places them into the req->out datastructure where +they can be returned to the system call through the "list of requests" +structure and request_send(). diff --git a/doc/html/annotated.html b/doc/html/annotated.html new file mode 100644 index 0000000..6edc3e6 --- /dev/null +++ b/doc/html/annotated.html @@ -0,0 +1,70 @@ + + + + + + + +libfuse: Data Structures + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+
+
Data Structures
+
+
+
Here are the data structures with brief descriptions:
+
+ + + + diff --git a/doc/html/bc_s.png b/doc/html/bc_s.png new file mode 100644 index 0000000..224b29a Binary files /dev/null and b/doc/html/bc_s.png differ diff --git a/doc/html/bdwn.png b/doc/html/bdwn.png new file mode 100644 index 0000000..940a0b9 Binary files /dev/null and b/doc/html/bdwn.png differ diff --git a/doc/html/buffer_8c_source.html b/doc/html/buffer_8c_source.html new file mode 100644 index 0000000..d1949d7 --- /dev/null +++ b/doc/html/buffer_8c_source.html @@ -0,0 +1,78 @@ + + + + + + + +libfuse: lib/buffer.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
buffer.c
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2010 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Functions for dealing with `struct fuse_buf` and `struct
6  fuse_bufvec`.
7 
8  This program can be distributed under the terms of the GNU LGPLv2.
9  See the file COPYING.LIB
10 */
11 
12 #define _GNU_SOURCE
13 
14 #include "config.h"
15 #include "fuse_i.h"
16 #include "fuse_lowlevel.h"
17 #include <string.h>
18 #include <unistd.h>
19 #include <errno.h>
20 #include <assert.h>
21 
22 size_t fuse_buf_size(const struct fuse_bufvec *bufv)
23 {
24  size_t i;
25  size_t size = 0;
26 
27  for (i = 0; i < bufv->count; i++) {
28  if (bufv->buf[i].size == SIZE_MAX)
29  size = SIZE_MAX;
30  else
31  size += bufv->buf[i].size;
32  }
33 
34  return size;
35 }
36 
37 static size_t min_size(size_t s1, size_t s2)
38 {
39  return s1 < s2 ? s1 : s2;
40 }
41 
42 static ssize_t fuse_buf_write(const struct fuse_buf *dst, size_t dst_off,
43  const struct fuse_buf *src, size_t src_off,
44  size_t len)
45 {
46  ssize_t res = 0;
47  size_t copied = 0;
48 
49  while (len) {
50  if (dst->flags & FUSE_BUF_FD_SEEK) {
51  res = pwrite(dst->fd, src->mem + src_off, len,
52  dst->pos + dst_off);
53  } else {
54  res = write(dst->fd, src->mem + src_off, len);
55  }
56  if (res == -1) {
57  if (!copied)
58  return -errno;
59  break;
60  }
61  if (res == 0)
62  break;
63 
64  copied += res;
65  if (!(dst->flags & FUSE_BUF_FD_RETRY))
66  break;
67 
68  src_off += res;
69  dst_off += res;
70  len -= res;
71  }
72 
73  return copied;
74 }
75 
76 static ssize_t fuse_buf_read(const struct fuse_buf *dst, size_t dst_off,
77  const struct fuse_buf *src, size_t src_off,
78  size_t len)
79 {
80  ssize_t res = 0;
81  size_t copied = 0;
82 
83  while (len) {
84  if (src->flags & FUSE_BUF_FD_SEEK) {
85  res = pread(src->fd, dst->mem + dst_off, len,
86  src->pos + src_off);
87  } else {
88  res = read(src->fd, dst->mem + dst_off, len);
89  }
90  if (res == -1) {
91  if (!copied)
92  return -errno;
93  break;
94  }
95  if (res == 0)
96  break;
97 
98  copied += res;
99  if (!(src->flags & FUSE_BUF_FD_RETRY))
100  break;
101 
102  dst_off += res;
103  src_off += res;
104  len -= res;
105  }
106 
107  return copied;
108 }
109 
110 static ssize_t fuse_buf_fd_to_fd(const struct fuse_buf *dst, size_t dst_off,
111  const struct fuse_buf *src, size_t src_off,
112  size_t len)
113 {
114  char buf[4096];
115  struct fuse_buf tmp = {
116  .size = sizeof(buf),
117  .flags = 0,
118  };
119  ssize_t res;
120  size_t copied = 0;
121 
122  tmp.mem = buf;
123 
124  while (len) {
125  size_t this_len = min_size(tmp.size, len);
126  size_t read_len;
127 
128  res = fuse_buf_read(&tmp, 0, src, src_off, this_len);
129  if (res < 0) {
130  if (!copied)
131  return res;
132  break;
133  }
134  if (res == 0)
135  break;
136 
137  read_len = res;
138  res = fuse_buf_write(dst, dst_off, &tmp, 0, read_len);
139  if (res < 0) {
140  if (!copied)
141  return res;
142  break;
143  }
144  if (res == 0)
145  break;
146 
147  copied += res;
148 
149  if (res < this_len)
150  break;
151 
152  dst_off += res;
153  src_off += res;
154  len -= res;
155  }
156 
157  return copied;
158 }
159 
160 #ifdef HAVE_SPLICE
161 static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
162  const struct fuse_buf *src, size_t src_off,
163  size_t len, enum fuse_buf_copy_flags flags)
164 {
165  int splice_flags = 0;
166  off_t *srcpos = NULL;
167  off_t *dstpos = NULL;
168  off_t srcpos_val;
169  off_t dstpos_val;
170  ssize_t res;
171  size_t copied = 0;
172 
173  if (flags & FUSE_BUF_SPLICE_MOVE)
174  splice_flags |= SPLICE_F_MOVE;
175  if (flags & FUSE_BUF_SPLICE_NONBLOCK)
176  splice_flags |= SPLICE_F_NONBLOCK;
177 
178  if (src->flags & FUSE_BUF_FD_SEEK) {
179  srcpos_val = src->pos + src_off;
180  srcpos = &srcpos_val;
181  }
182  if (dst->flags & FUSE_BUF_FD_SEEK) {
183  dstpos_val = dst->pos + dst_off;
184  dstpos = &dstpos_val;
185  }
186 
187  while (len) {
188  res = splice(src->fd, srcpos, dst->fd, dstpos, len,
189  splice_flags);
190  if (res == -1) {
191  if (copied)
192  break;
193 
194  if (errno != EINVAL || (flags & FUSE_BUF_FORCE_SPLICE))
195  return -errno;
196 
197  /* Maybe splice is not supported for this combination */
198  return fuse_buf_fd_to_fd(dst, dst_off, src, src_off,
199  len);
200  }
201  if (res == 0)
202  break;
203 
204  copied += res;
205  if (!(src->flags & FUSE_BUF_FD_RETRY) &&
206  !(dst->flags & FUSE_BUF_FD_RETRY)) {
207  break;
208  }
209 
210  len -= res;
211  }
212 
213  return copied;
214 }
215 #else
216 static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
217  const struct fuse_buf *src, size_t src_off,
218  size_t len, enum fuse_buf_copy_flags flags)
219 {
220  (void) flags;
221 
222  return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
223 }
224 #endif
225 
226 
227 static ssize_t fuse_buf_copy_one(const struct fuse_buf *dst, size_t dst_off,
228  const struct fuse_buf *src, size_t src_off,
229  size_t len, enum fuse_buf_copy_flags flags)
230 {
231  int src_is_fd = src->flags & FUSE_BUF_IS_FD;
232  int dst_is_fd = dst->flags & FUSE_BUF_IS_FD;
233 
234  if (!src_is_fd && !dst_is_fd) {
235  void *dstmem = dst->mem + dst_off;
236  void *srcmem = src->mem + src_off;
237 
238  if (dstmem != srcmem) {
239  if (dstmem + len <= srcmem || srcmem + len <= dstmem)
240  memcpy(dstmem, srcmem, len);
241  else
242  memmove(dstmem, srcmem, len);
243  }
244 
245  return len;
246  } else if (!src_is_fd) {
247  return fuse_buf_write(dst, dst_off, src, src_off, len);
248  } else if (!dst_is_fd) {
249  return fuse_buf_read(dst, dst_off, src, src_off, len);
250  } else if (flags & FUSE_BUF_NO_SPLICE) {
251  return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
252  } else {
253  return fuse_buf_splice(dst, dst_off, src, src_off, len, flags);
254  }
255 }
256 
257 static const struct fuse_buf *fuse_bufvec_current(struct fuse_bufvec *bufv)
258 {
259  if (bufv->idx < bufv->count)
260  return &bufv->buf[bufv->idx];
261  else
262  return NULL;
263 }
264 
265 static int fuse_bufvec_advance(struct fuse_bufvec *bufv, size_t len)
266 {
267  const struct fuse_buf *buf = fuse_bufvec_current(bufv);
268 
269  bufv->off += len;
270  assert(bufv->off <= buf->size);
271  if (bufv->off == buf->size) {
272  assert(bufv->idx < bufv->count);
273  bufv->idx++;
274  if (bufv->idx == bufv->count)
275  return 0;
276  bufv->off = 0;
277  }
278  return 1;
279 }
280 
281 ssize_t fuse_buf_copy(struct fuse_bufvec *dstv, struct fuse_bufvec *srcv,
283 {
284  size_t copied = 0;
285 
286  if (dstv == srcv)
287  return fuse_buf_size(dstv);
288 
289  for (;;) {
290  const struct fuse_buf *src = fuse_bufvec_current(srcv);
291  const struct fuse_buf *dst = fuse_bufvec_current(dstv);
292  size_t src_len;
293  size_t dst_len;
294  size_t len;
295  ssize_t res;
296 
297  if (src == NULL || dst == NULL)
298  break;
299 
300  src_len = src->size - srcv->off;
301  dst_len = dst->size - dstv->off;
302  len = min_size(src_len, dst_len);
303 
304  res = fuse_buf_copy_one(dst, dstv->off, src, srcv->off, len, flags);
305  if (res < 0) {
306  if (!copied)
307  return res;
308  break;
309  }
310  copied += res;
311 
312  if (!fuse_bufvec_advance(srcv, res) ||
313  !fuse_bufvec_advance(dstv, res))
314  break;
315 
316  if (res < len)
317  break;
318  }
319 
320  return copied;
321 }
size_t off
Definition: fuse_common.h:679
+ + + + +
off_t pos
Definition: fuse_common.h:654
+ +
size_t idx
Definition: fuse_common.h:674
+
size_t count
Definition: fuse_common.h:669
+
enum fuse_buf_flags flags
Definition: fuse_common.h:633
+ +
void * mem
Definition: fuse_common.h:640
+ + +
struct fuse_buf buf[1]
Definition: fuse_common.h:684
+ +
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
Definition: buffer.c:22
+
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
Definition: buffer.c:281
+
size_t size
Definition: fuse_common.h:628
+
fuse_buf_copy_flags
Definition: fuse_common.h:579
+ + +
+ + + + diff --git a/doc/html/classes.html b/doc/html/classes.html new file mode 100644 index 0000000..e849cdc --- /dev/null +++ b/doc/html/classes.html @@ -0,0 +1,62 @@ + + + + + + + +libfuse: Data Structure Index + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+
+
Data Structure Index
+
+
+ + + + + + + +
  f  
+
fuse_bufvec   fuse_ctx   fuse_lowlevel_ops   
fuse_config   fuse_entry_param   fuse_module   
fuse_args   fuse_conn_info   fuse_file_info   fuse_operations   
fuse_buf   fuse_context   fuse_loop_config   fuse_opt   
+ +
+ + + + diff --git a/doc/html/closed.png b/doc/html/closed.png new file mode 100644 index 0000000..98cc2c9 Binary files /dev/null and b/doc/html/closed.png differ diff --git a/doc/html/config_8h_source.html b/doc/html/config_8h_source.html new file mode 100644 index 0000000..82b17f6 --- /dev/null +++ b/doc/html/config_8h_source.html @@ -0,0 +1,56 @@ + + + + + + + +libfuse: build/config.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
config.h
+
+
+
1 /*
2  * Autogenerated by the Meson build system.
3  * Do not edit, your changes will be lost.
4  */
5 
6 #pragma once
7 
8 #undef HAVE_COPY_FILE_RANGE
9 
10 #define HAVE_FDATASYNC
11 
12 #define HAVE_FORK
13 
14 #define HAVE_FSTATAT
15 
16 #define HAVE_ICONV
17 
18 #define HAVE_OPENAT
19 
20 #define HAVE_PIPE2
21 
22 #define HAVE_POSIX_FALLOCATE
23 
24 #define HAVE_READLINKAT
25 
26 #define HAVE_SETXATTR
27 
28 #define HAVE_SPLICE
29 
30 #define HAVE_STRUCT_STAT_ST_ATIM
31 
32 #undef HAVE_STRUCT_STAT_ST_ATIMESPEC
33 
34 #define HAVE_UTIMENSAT
35 
36 #define HAVE_VMSPLICE
37 
38 #define PACKAGE_VERSION "3.4.0"
39 
+ + + + diff --git a/doc/html/cuse_8c.html b/doc/html/cuse_8c.html new file mode 100644 index 0000000..c722500 --- /dev/null +++ b/doc/html/cuse_8c.html @@ -0,0 +1,75 @@ + + + + + + + +libfuse: example/cuse.c File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
cuse.c File Reference
+
+
+
#include <cuse_lowlevel.h>
+#include <fuse_opt.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include "ioctl.h"
+
+

Go to the source code of this file.

+

Detailed Description

+

This example demonstrates how to implement a character device in userspace ("CUSE"). This is only allowed for root. The character device should appear in /dev under the specified name. It can be tested with the cuse_client.c program.

+

Mount the file system with:

cuse -f --name=mydevice
+

You should now have a new /dev/mydevice character device. To "unmount" it, kill the "cuse" process.

+

To compile this example, run

gcc -Wall cuse.c `pkg-config fuse3 --cflags --libs` -o cuse
+

Source code

+
/*
CUSE example: Character device in Userspace
Copyright (C) 2008-2009 SUSE Linux Products GmbH
Copyright (C) 2008-2009 Tejun Heo <tj@kernel.org>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
*/
#define FUSE_USE_VERSION 31
#include <cuse_lowlevel.h>
#include <fuse_opt.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "ioctl.h"
static void *cusexmp_buf;
static size_t cusexmp_size;
static const char *usage =
"usage: cusexmp [options]\n"
"\n"
"options:\n"
" --help|-h print this help message\n"
" --maj=MAJ|-M MAJ device major number\n"
" --min=MIN|-m MIN device minor number\n"
" --name=NAME|-n NAME device name (mandatory)\n"
" -d -o debug enable debug output (implies -f)\n"
" -f foreground operation\n"
" -s disable multi-threaded operation\n"
"\n";
static int cusexmp_resize(size_t new_size)
{
void *new_buf;
if (new_size == cusexmp_size)
return 0;
new_buf = realloc(cusexmp_buf, new_size);
if (!new_buf && new_size)
return -ENOMEM;
if (new_size > cusexmp_size)
memset(new_buf + cusexmp_size, 0, new_size - cusexmp_size);
cusexmp_buf = new_buf;
cusexmp_size = new_size;
return 0;
}
static int cusexmp_expand(size_t new_size)
{
if (new_size > cusexmp_size)
return cusexmp_resize(new_size);
return 0;
}
static void cusexmp_open(fuse_req_t req, struct fuse_file_info *fi)
{
fuse_reply_open(req, fi);
}
static void cusexmp_read(fuse_req_t req, size_t size, off_t off,
struct fuse_file_info *fi)
{
(void)fi;
if (off >= cusexmp_size)
off = cusexmp_size;
if (size > cusexmp_size - off)
size = cusexmp_size - off;
fuse_reply_buf(req, cusexmp_buf + off, size);
}
static void cusexmp_write(fuse_req_t req, const char *buf, size_t size,
off_t off, struct fuse_file_info *fi)
{
(void)fi;
if (cusexmp_expand(off + size)) {
fuse_reply_err(req, ENOMEM);
return;
}
memcpy(cusexmp_buf + off, buf, size);
fuse_reply_write(req, size);
}
static void fioc_do_rw(fuse_req_t req, void *addr, const void *in_buf,
size_t in_bufsz, size_t out_bufsz, int is_read)
{
const struct fioc_rw_arg *arg;
struct iovec in_iov[2], out_iov[3], iov[3];
size_t cur_size;
/* read in arg */
in_iov[0].iov_base = addr;
in_iov[0].iov_len = sizeof(*arg);
if (!in_bufsz) {
fuse_reply_ioctl_retry(req, in_iov, 1, NULL, 0);
return;
}
arg = in_buf;
in_buf += sizeof(*arg);
in_bufsz -= sizeof(*arg);
/* prepare size outputs */
out_iov[0].iov_base =
addr + offsetof(struct fioc_rw_arg, prev_size);
out_iov[0].iov_len = sizeof(arg->prev_size);
out_iov[1].iov_base =
addr + offsetof(struct fioc_rw_arg, new_size);
out_iov[1].iov_len = sizeof(arg->new_size);
/* prepare client buf */
if (is_read) {
out_iov[2].iov_base = arg->buf;
out_iov[2].iov_len = arg->size;
if (!out_bufsz) {
fuse_reply_ioctl_retry(req, in_iov, 1, out_iov, 3);
return;
}
} else {
in_iov[1].iov_base = arg->buf;
in_iov[1].iov_len = arg->size;
if (arg->size && !in_bufsz) {
fuse_reply_ioctl_retry(req, in_iov, 2, out_iov, 2);
return;
}
}
/* we're all set */
cur_size = cusexmp_size;
iov[0].iov_base = &cur_size;
iov[0].iov_len = sizeof(cur_size);
iov[1].iov_base = &cusexmp_size;
iov[1].iov_len = sizeof(cusexmp_size);
if (is_read) {
size_t off = arg->offset;
size_t size = arg->size;
if (off >= cusexmp_size)
off = cusexmp_size;
if (size > cusexmp_size - off)
size = cusexmp_size - off;
iov[2].iov_base = cusexmp_buf + off;
iov[2].iov_len = size;
fuse_reply_ioctl_iov(req, size, iov, 3);
} else {
if (cusexmp_expand(arg->offset + in_bufsz)) {
fuse_reply_err(req, ENOMEM);
return;
}
memcpy(cusexmp_buf + arg->offset, in_buf, in_bufsz);
fuse_reply_ioctl_iov(req, in_bufsz, iov, 2);
}
}
static void cusexmp_ioctl(fuse_req_t req, int cmd, void *arg,
struct fuse_file_info *fi, unsigned flags,
const void *in_buf, size_t in_bufsz, size_t out_bufsz)
{
int is_read = 0;
(void)fi;
if (flags & FUSE_IOCTL_COMPAT) {
fuse_reply_err(req, ENOSYS);
return;
}
switch (cmd) {
case FIOC_GET_SIZE:
if (!out_bufsz) {
struct iovec iov = { arg, sizeof(size_t) };
fuse_reply_ioctl_retry(req, NULL, 0, &iov, 1);
} else
fuse_reply_ioctl(req, 0, &cusexmp_size,
sizeof(cusexmp_size));
break;
case FIOC_SET_SIZE:
if (!in_bufsz) {
struct iovec iov = { arg, sizeof(size_t) };
fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
} else {
cusexmp_resize(*(size_t *)in_buf);
fuse_reply_ioctl(req, 0, NULL, 0);
}
break;
case FIOC_READ:
is_read = 1;
/* fall through */
case FIOC_WRITE:
fioc_do_rw(req, arg, in_buf, in_bufsz, out_bufsz, is_read);
break;
default:
fuse_reply_err(req, EINVAL);
}
}
struct cusexmp_param {
unsigned major;
unsigned minor;
char *dev_name;
int is_help;
};
#define CUSEXMP_OPT(t, p) { t, offsetof(struct cusexmp_param, p), 1 }
static const struct fuse_opt cusexmp_opts[] = {
CUSEXMP_OPT("-M %u", major),
CUSEXMP_OPT("--maj=%u", major),
CUSEXMP_OPT("-m %u", minor),
CUSEXMP_OPT("--min=%u", minor),
CUSEXMP_OPT("-n %s", dev_name),
CUSEXMP_OPT("--name=%s", dev_name),
FUSE_OPT_KEY("-h", 0),
FUSE_OPT_KEY("--help", 0),
};
static int cusexmp_process_arg(void *data, const char *arg, int key,
struct fuse_args *outargs)
{
struct cusexmp_param *param = data;
(void)outargs;
(void)arg;
switch (key) {
case 0:
param->is_help = 1;
fprintf(stderr, "%s", usage);
return fuse_opt_add_arg(outargs, "-ho");
default:
return 1;
}
}
static const struct cuse_lowlevel_ops cusexmp_clop = {
.open = cusexmp_open,
.read = cusexmp_read,
.write = cusexmp_write,
.ioctl = cusexmp_ioctl,
};
int main(int argc, char **argv)
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
struct cusexmp_param param = { 0, 0, NULL, 0 };
char dev_name[128] = "DEVNAME=";
const char *dev_info_argv[] = { dev_name };
struct cuse_info ci;
if (fuse_opt_parse(&args, &param, cusexmp_opts, cusexmp_process_arg)) {
printf("failed to parse option\n");
return 1;
}
if (!param.is_help) {
if (!param.dev_name) {
fprintf(stderr, "Error: device name missing\n");
return 1;
}
strncat(dev_name, param.dev_name, sizeof(dev_name) - 9);
}
memset(&ci, 0, sizeof(ci));
ci.dev_major = param.major;
ci.dev_minor = param.minor;
ci.dev_info_argc = 1;
ci.dev_info_argv = dev_info_argv;
ci.flags = CUSE_UNRESTRICTED_IOCTL;
return cuse_lowlevel_main(args.argc, args.argv, &ci, &cusexmp_clop,
NULL);
}
+

Definition in file cuse.c.

+
+ + + + diff --git a/doc/html/cuse_8c_source.html b/doc/html/cuse_8c_source.html new file mode 100644 index 0000000..02827fe --- /dev/null +++ b/doc/html/cuse_8c_source.html @@ -0,0 +1,77 @@ + + + + + + + +libfuse: example/cuse.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
cuse.c
+
+
+Go to the documentation of this file.
1 /*
2  CUSE example: Character device in Userspace
3  Copyright (C) 2008-2009 SUSE Linux Products GmbH
4  Copyright (C) 2008-2009 Tejun Heo <tj@kernel.org>
5 
6  This program can be distributed under the terms of the GNU GPL.
7  See the file COPYING.
8 
9 */
10 
34 #define FUSE_USE_VERSION 31
35 
36 #include <cuse_lowlevel.h>
37 #include <fuse_opt.h>
38 #include <stddef.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <errno.h>
44 
45 #include "ioctl.h"
46 
47 static void *cusexmp_buf;
48 static size_t cusexmp_size;
49 
50 static const char *usage =
51 "usage: cusexmp [options]\n"
52 "\n"
53 "options:\n"
54 " --help|-h print this help message\n"
55 " --maj=MAJ|-M MAJ device major number\n"
56 " --min=MIN|-m MIN device minor number\n"
57 " --name=NAME|-n NAME device name (mandatory)\n"
58 " -d -o debug enable debug output (implies -f)\n"
59 " -f foreground operation\n"
60 " -s disable multi-threaded operation\n"
61 "\n";
62 
63 static int cusexmp_resize(size_t new_size)
64 {
65  void *new_buf;
66 
67  if (new_size == cusexmp_size)
68  return 0;
69 
70  new_buf = realloc(cusexmp_buf, new_size);
71  if (!new_buf && new_size)
72  return -ENOMEM;
73 
74  if (new_size > cusexmp_size)
75  memset(new_buf + cusexmp_size, 0, new_size - cusexmp_size);
76 
77  cusexmp_buf = new_buf;
78  cusexmp_size = new_size;
79 
80  return 0;
81 }
82 
83 static int cusexmp_expand(size_t new_size)
84 {
85  if (new_size > cusexmp_size)
86  return cusexmp_resize(new_size);
87  return 0;
88 }
89 
90 static void cusexmp_open(fuse_req_t req, struct fuse_file_info *fi)
91 {
92  fuse_reply_open(req, fi);
93 }
94 
95 static void cusexmp_read(fuse_req_t req, size_t size, off_t off,
96  struct fuse_file_info *fi)
97 {
98  (void)fi;
99 
100  if (off >= cusexmp_size)
101  off = cusexmp_size;
102  if (size > cusexmp_size - off)
103  size = cusexmp_size - off;
104 
105  fuse_reply_buf(req, cusexmp_buf + off, size);
106 }
107 
108 static void cusexmp_write(fuse_req_t req, const char *buf, size_t size,
109  off_t off, struct fuse_file_info *fi)
110 {
111  (void)fi;
112 
113  if (cusexmp_expand(off + size)) {
114  fuse_reply_err(req, ENOMEM);
115  return;
116  }
117 
118  memcpy(cusexmp_buf + off, buf, size);
119  fuse_reply_write(req, size);
120 }
121 
122 static void fioc_do_rw(fuse_req_t req, void *addr, const void *in_buf,
123  size_t in_bufsz, size_t out_bufsz, int is_read)
124 {
125  const struct fioc_rw_arg *arg;
126  struct iovec in_iov[2], out_iov[3], iov[3];
127  size_t cur_size;
128 
129  /* read in arg */
130  in_iov[0].iov_base = addr;
131  in_iov[0].iov_len = sizeof(*arg);
132  if (!in_bufsz) {
133  fuse_reply_ioctl_retry(req, in_iov, 1, NULL, 0);
134  return;
135  }
136  arg = in_buf;
137  in_buf += sizeof(*arg);
138  in_bufsz -= sizeof(*arg);
139 
140  /* prepare size outputs */
141  out_iov[0].iov_base =
142  addr + offsetof(struct fioc_rw_arg, prev_size);
143  out_iov[0].iov_len = sizeof(arg->prev_size);
144 
145  out_iov[1].iov_base =
146  addr + offsetof(struct fioc_rw_arg, new_size);
147  out_iov[1].iov_len = sizeof(arg->new_size);
148 
149  /* prepare client buf */
150  if (is_read) {
151  out_iov[2].iov_base = arg->buf;
152  out_iov[2].iov_len = arg->size;
153  if (!out_bufsz) {
154  fuse_reply_ioctl_retry(req, in_iov, 1, out_iov, 3);
155  return;
156  }
157  } else {
158  in_iov[1].iov_base = arg->buf;
159  in_iov[1].iov_len = arg->size;
160  if (arg->size && !in_bufsz) {
161  fuse_reply_ioctl_retry(req, in_iov, 2, out_iov, 2);
162  return;
163  }
164  }
165 
166  /* we're all set */
167  cur_size = cusexmp_size;
168  iov[0].iov_base = &cur_size;
169  iov[0].iov_len = sizeof(cur_size);
170 
171  iov[1].iov_base = &cusexmp_size;
172  iov[1].iov_len = sizeof(cusexmp_size);
173 
174  if (is_read) {
175  size_t off = arg->offset;
176  size_t size = arg->size;
177 
178  if (off >= cusexmp_size)
179  off = cusexmp_size;
180  if (size > cusexmp_size - off)
181  size = cusexmp_size - off;
182 
183  iov[2].iov_base = cusexmp_buf + off;
184  iov[2].iov_len = size;
185  fuse_reply_ioctl_iov(req, size, iov, 3);
186  } else {
187  if (cusexmp_expand(arg->offset + in_bufsz)) {
188  fuse_reply_err(req, ENOMEM);
189  return;
190  }
191 
192  memcpy(cusexmp_buf + arg->offset, in_buf, in_bufsz);
193  fuse_reply_ioctl_iov(req, in_bufsz, iov, 2);
194  }
195 }
196 
197 static void cusexmp_ioctl(fuse_req_t req, int cmd, void *arg,
198  struct fuse_file_info *fi, unsigned flags,
199  const void *in_buf, size_t in_bufsz, size_t out_bufsz)
200 {
201  int is_read = 0;
202 
203  (void)fi;
204 
205  if (flags & FUSE_IOCTL_COMPAT) {
206  fuse_reply_err(req, ENOSYS);
207  return;
208  }
209 
210  switch (cmd) {
211  case FIOC_GET_SIZE:
212  if (!out_bufsz) {
213  struct iovec iov = { arg, sizeof(size_t) };
214 
215  fuse_reply_ioctl_retry(req, NULL, 0, &iov, 1);
216  } else
217  fuse_reply_ioctl(req, 0, &cusexmp_size,
218  sizeof(cusexmp_size));
219  break;
220 
221  case FIOC_SET_SIZE:
222  if (!in_bufsz) {
223  struct iovec iov = { arg, sizeof(size_t) };
224 
225  fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
226  } else {
227  cusexmp_resize(*(size_t *)in_buf);
228  fuse_reply_ioctl(req, 0, NULL, 0);
229  }
230  break;
231 
232  case FIOC_READ:
233  is_read = 1;
234  /* fall through */
235  case FIOC_WRITE:
236  fioc_do_rw(req, arg, in_buf, in_bufsz, out_bufsz, is_read);
237  break;
238 
239  default:
240  fuse_reply_err(req, EINVAL);
241  }
242 }
243 
244 struct cusexmp_param {
245  unsigned major;
246  unsigned minor;
247  char *dev_name;
248  int is_help;
249 };
250 
251 #define CUSEXMP_OPT(t, p) { t, offsetof(struct cusexmp_param, p), 1 }
252 
253 static const struct fuse_opt cusexmp_opts[] = {
254  CUSEXMP_OPT("-M %u", major),
255  CUSEXMP_OPT("--maj=%u", major),
256  CUSEXMP_OPT("-m %u", minor),
257  CUSEXMP_OPT("--min=%u", minor),
258  CUSEXMP_OPT("-n %s", dev_name),
259  CUSEXMP_OPT("--name=%s", dev_name),
260  FUSE_OPT_KEY("-h", 0),
261  FUSE_OPT_KEY("--help", 0),
263 };
264 
265 static int cusexmp_process_arg(void *data, const char *arg, int key,
266  struct fuse_args *outargs)
267 {
268  struct cusexmp_param *param = data;
269 
270  (void)outargs;
271  (void)arg;
272 
273  switch (key) {
274  case 0:
275  param->is_help = 1;
276  fprintf(stderr, "%s", usage);
277  return fuse_opt_add_arg(outargs, "-ho");
278  default:
279  return 1;
280  }
281 }
282 
283 static const struct cuse_lowlevel_ops cusexmp_clop = {
284  .open = cusexmp_open,
285  .read = cusexmp_read,
286  .write = cusexmp_write,
287  .ioctl = cusexmp_ioctl,
288 };
289 
290 int main(int argc, char **argv)
291 {
292  struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
293  struct cusexmp_param param = { 0, 0, NULL, 0 };
294  char dev_name[128] = "DEVNAME=";
295  const char *dev_info_argv[] = { dev_name };
296  struct cuse_info ci;
297 
298  if (fuse_opt_parse(&args, &param, cusexmp_opts, cusexmp_process_arg)) {
299  printf("failed to parse option\n");
300  return 1;
301  }
302 
303  if (!param.is_help) {
304  if (!param.dev_name) {
305  fprintf(stderr, "Error: device name missing\n");
306  return 1;
307  }
308  strncat(dev_name, param.dev_name, sizeof(dev_name) - 9);
309  }
310 
311  memset(&ci, 0, sizeof(ci));
312  ci.dev_major = param.major;
313  ci.dev_minor = param.minor;
314  ci.dev_info_argc = 1;
315  ci.dev_info_argv = dev_info_argv;
316  ci.flags = CUSE_UNRESTRICTED_IOCTL;
317 
318  return cuse_lowlevel_main(args.argc, args.argv, &ci, &cusexmp_clop,
319  NULL);
320 }
int fuse_reply_err(fuse_req_t req, int err)
+
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
+
int argc
Definition: fuse_opt.h:111
+
int fuse_reply_ioctl_retry(fuse_req_t req, const struct iovec *in_iov, size_t in_count, const struct iovec *out_iov, size_t out_count)
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
+
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:54
+ +
int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov, int count)
+ +
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98
+
#define FUSE_IOCTL_COMPAT
Definition: fuse_common.h:329
+
#define FUSE_OPT_END
Definition: fuse_opt.h:104
+
char ** argv
Definition: fuse_opt.h:114
+
int fuse_reply_write(fuse_req_t req, size_t count)
+
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
+ + +
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
+ +
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
+
+ + + + diff --git a/doc/html/cuse__client_8c.html b/doc/html/cuse__client_8c.html new file mode 100644 index 0000000..5e14520 --- /dev/null +++ b/doc/html/cuse__client_8c.html @@ -0,0 +1,86 @@ + + + + + + + +libfuse: example/cuse_client.c File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
cuse_client.c File Reference
+
+
+
#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include "ioctl.h"
+
+

Go to the source code of this file.

+

Detailed Description

+

This program tests the cuse.c example file system.

+

Example usage (assuming that /dev/foobar is a CUSE device provided by the cuse.c example file system):

$ cuse_client /dev/foobar s
+0
+
+$ echo "hello" | cuse_client /dev/foobar w 6
+Writing 6 bytes
+transferred 6 bytes (0 -> 6)
+
+$ cuse_client /dev/foobar s
+6
+
+$ cuse_client /dev/foobar r 10
+hello
+transferred 6 bytes (6 -> 6)
+

Compiling this example

gcc -Wall cuse_client.c -o cuse_client
+

Source Code

+
/*
FUSE fioclient: FUSE ioctl example client
Copyright (C) 2008 SUSE Linux Products GmbH
Copyright (C) 2008 Tejun Heo <teheo@suse.de>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
*/
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include "ioctl.h"
const char *usage =
"Usage: cuse_client FIOC_FILE COMMAND\n"
"\n"
"COMMANDS\n"
" s [SIZE] : get size if SIZE is omitted, set size otherwise\n"
" r SIZE [OFF] : read SIZE bytes @ OFF (dfl 0) and output to stdout\n"
" w SIZE [OFF] : write SIZE bytes @ OFF (dfl 0) from stdin\n"
"\n";
static int do_rw(int fd, int is_read, size_t size, off_t offset,
size_t *prev_size, size_t *new_size)
{
struct fioc_rw_arg arg = { .offset = offset };
ssize_t ret;
arg.buf = calloc(1, size);
if (!arg.buf) {
fprintf(stderr, "failed to allocated %zu bytes\n", size);
return -1;
}
if (is_read) {
arg.size = size;
ret = ioctl(fd, FIOC_READ, &arg);
if (ret >= 0)
fwrite(arg.buf, 1, ret, stdout);
} else {
arg.size = fread(arg.buf, 1, size, stdin);
fprintf(stderr, "Writing %zu bytes\n", arg.size);
ret = ioctl(fd, FIOC_WRITE, &arg);
}
if (ret >= 0) {
*prev_size = arg.prev_size;
*new_size = arg.new_size;
} else
perror("ioctl");
free(arg.buf);
return ret;
}
int main(int argc, char **argv)
{
size_t param[2] = { };
size_t size, prev_size = 0, new_size = 0;
char cmd;
int fd, i, rc;
if (argc < 3)
goto usage;
fd = open(argv[1], O_RDWR);
if (fd < 0) {
perror("open");
return 1;
}
cmd = tolower(argv[2][0]);
argc -= 3;
argv += 3;
for (i = 0; i < argc; i++) {
char *endp;
param[i] = strtoul(argv[i], &endp, 0);
if (endp == argv[i] || *endp != '\0')
goto usage;
}
switch (cmd) {
case 's':
if (!argc) {
if (ioctl(fd, FIOC_GET_SIZE, &size)) {
perror("ioctl");
return 1;
}
printf("%zu\n", size);
} else {
size = param[0];
if (ioctl(fd, FIOC_SET_SIZE, &size)) {
perror("ioctl");
return 1;
}
}
return 0;
case 'r':
case 'w':
rc = do_rw(fd, cmd == 'r', param[0], param[1],
&prev_size, &new_size);
if (rc < 0)
return 1;
fprintf(stderr, "transferred %d bytes (%zu -> %zu)\n",
rc, prev_size, new_size);
return 0;
}
usage:
fprintf(stderr, "%s", usage);
return 1;
}
+

Definition in file cuse_client.c.

+
+ + + + diff --git a/doc/html/cuse__client_8c_source.html b/doc/html/cuse__client_8c_source.html new file mode 100644 index 0000000..5df3811 --- /dev/null +++ b/doc/html/cuse__client_8c_source.html @@ -0,0 +1,57 @@ + + + + + + + +libfuse: example/cuse_client.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
cuse_client.c
+
+
+Go to the documentation of this file.
1 /*
2  FUSE fioclient: FUSE ioctl example client
3  Copyright (C) 2008 SUSE Linux Products GmbH
4  Copyright (C) 2008 Tejun Heo <teheo@suse.de>
5 
6  This program can be distributed under the terms of the GNU GPL.
7  See the file COPYING.
8 */
9 
40 #include <sys/types.h>
41 #include <fcntl.h>
42 #include <sys/stat.h>
43 #include <sys/ioctl.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <ctype.h>
47 #include <errno.h>
48 #include "ioctl.h"
49 
50 const char *usage =
51 "Usage: cuse_client FIOC_FILE COMMAND\n"
52 "\n"
53 "COMMANDS\n"
54 " s [SIZE] : get size if SIZE is omitted, set size otherwise\n"
55 " r SIZE [OFF] : read SIZE bytes @ OFF (dfl 0) and output to stdout\n"
56 " w SIZE [OFF] : write SIZE bytes @ OFF (dfl 0) from stdin\n"
57 "\n";
58 
59 static int do_rw(int fd, int is_read, size_t size, off_t offset,
60  size_t *prev_size, size_t *new_size)
61 {
62  struct fioc_rw_arg arg = { .offset = offset };
63  ssize_t ret;
64 
65  arg.buf = calloc(1, size);
66  if (!arg.buf) {
67  fprintf(stderr, "failed to allocated %zu bytes\n", size);
68  return -1;
69  }
70 
71  if (is_read) {
72  arg.size = size;
73  ret = ioctl(fd, FIOC_READ, &arg);
74  if (ret >= 0)
75  fwrite(arg.buf, 1, ret, stdout);
76  } else {
77  arg.size = fread(arg.buf, 1, size, stdin);
78  fprintf(stderr, "Writing %zu bytes\n", arg.size);
79  ret = ioctl(fd, FIOC_WRITE, &arg);
80  }
81 
82  if (ret >= 0) {
83  *prev_size = arg.prev_size;
84  *new_size = arg.new_size;
85  } else
86  perror("ioctl");
87 
88  free(arg.buf);
89  return ret;
90 }
91 
92 int main(int argc, char **argv)
93 {
94  size_t param[2] = { };
95  size_t size, prev_size = 0, new_size = 0;
96  char cmd;
97  int fd, i, rc;
98 
99  if (argc < 3)
100  goto usage;
101 
102  fd = open(argv[1], O_RDWR);
103  if (fd < 0) {
104  perror("open");
105  return 1;
106  }
107 
108  cmd = tolower(argv[2][0]);
109  argc -= 3;
110  argv += 3;
111 
112  for (i = 0; i < argc; i++) {
113  char *endp;
114  param[i] = strtoul(argv[i], &endp, 0);
115  if (endp == argv[i] || *endp != '\0')
116  goto usage;
117  }
118 
119  switch (cmd) {
120  case 's':
121  if (!argc) {
122  if (ioctl(fd, FIOC_GET_SIZE, &size)) {
123  perror("ioctl");
124  return 1;
125  }
126  printf("%zu\n", size);
127  } else {
128  size = param[0];
129  if (ioctl(fd, FIOC_SET_SIZE, &size)) {
130  perror("ioctl");
131  return 1;
132  }
133  }
134  return 0;
135 
136  case 'r':
137  case 'w':
138  rc = do_rw(fd, cmd == 'r', param[0], param[1],
139  &prev_size, &new_size);
140  if (rc < 0)
141  return 1;
142  fprintf(stderr, "transferred %d bytes (%zu -> %zu)\n",
143  rc, prev_size, new_size);
144  return 0;
145  }
146 
147  usage:
148  fprintf(stderr, "%s", usage);
149  return 1;
150 }
+
+ + + + diff --git a/doc/html/cuse__lowlevel_8c_source.html b/doc/html/cuse__lowlevel_8c_source.html new file mode 100644 index 0000000..12c8a1e --- /dev/null +++ b/doc/html/cuse__lowlevel_8c_source.html @@ -0,0 +1,79 @@ + + + + + + + +libfuse: lib/cuse_lowlevel.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
cuse_lowlevel.c
+
+
+
1 /*
2  CUSE: Character device in Userspace
3  Copyright (C) 2008 SUSE Linux Products GmbH
4  Copyright (C) 2008 Tejun Heo <teheo@suse.de>
5 
6  This program can be distributed under the terms of the GNU LGPLv2.
7  See the file COPYING.LIB.
8 */
9 
10 #include "config.h"
11 #include "cuse_lowlevel.h"
12 #include "fuse_kernel.h"
13 #include "fuse_i.h"
14 #include "fuse_opt.h"
15 
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <stddef.h>
20 #include <errno.h>
21 #include <unistd.h>
22 
23 struct cuse_data {
24  struct cuse_lowlevel_ops clop;
25  unsigned max_read;
26  unsigned dev_major;
27  unsigned dev_minor;
28  unsigned flags;
29  unsigned dev_info_len;
30  char dev_info[];
31 };
32 
33 static struct cuse_lowlevel_ops *req_clop(fuse_req_t req)
34 {
35  return &req->se->cuse_data->clop;
36 }
37 
38 static void cuse_fll_open(fuse_req_t req, fuse_ino_t ino,
39  struct fuse_file_info *fi)
40 {
41  (void)ino;
42  req_clop(req)->open(req, fi);
43 }
44 
45 static void cuse_fll_read(fuse_req_t req, fuse_ino_t ino, size_t size,
46  off_t off, struct fuse_file_info *fi)
47 {
48  (void)ino;
49  req_clop(req)->read(req, size, off, fi);
50 }
51 
52 static void cuse_fll_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
53  size_t size, off_t off, struct fuse_file_info *fi)
54 {
55  (void)ino;
56  req_clop(req)->write(req, buf, size, off, fi);
57 }
58 
59 static void cuse_fll_flush(fuse_req_t req, fuse_ino_t ino,
60  struct fuse_file_info *fi)
61 {
62  (void)ino;
63  req_clop(req)->flush(req, fi);
64 }
65 
66 static void cuse_fll_release(fuse_req_t req, fuse_ino_t ino,
67  struct fuse_file_info *fi)
68 {
69  (void)ino;
70  req_clop(req)->release(req, fi);
71 }
72 
73 static void cuse_fll_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
74  struct fuse_file_info *fi)
75 {
76  (void)ino;
77  req_clop(req)->fsync(req, datasync, fi);
78 }
79 
80 static void cuse_fll_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
81  struct fuse_file_info *fi, unsigned int flags,
82  const void *in_buf, size_t in_bufsz, size_t out_bufsz)
83 {
84  (void)ino;
85  req_clop(req)->ioctl(req, cmd, arg, fi, flags, in_buf, in_bufsz,
86  out_bufsz);
87 }
88 
89 static void cuse_fll_poll(fuse_req_t req, fuse_ino_t ino,
90  struct fuse_file_info *fi, struct fuse_pollhandle *ph)
91 {
92  (void)ino;
93  req_clop(req)->poll(req, fi, ph);
94 }
95 
96 static size_t cuse_pack_info(int argc, const char **argv, char *buf)
97 {
98  size_t size = 0;
99  int i;
100 
101  for (i = 0; i < argc; i++) {
102  size_t len;
103 
104  len = strlen(argv[i]) + 1;
105  size += len;
106  if (buf) {
107  memcpy(buf, argv[i], len);
108  buf += len;
109  }
110  }
111 
112  return size;
113 }
114 
115 static struct cuse_data *cuse_prep_data(const struct cuse_info *ci,
116  const struct cuse_lowlevel_ops *clop)
117 {
118  struct cuse_data *cd;
119  size_t dev_info_len;
120 
121  dev_info_len = cuse_pack_info(ci->dev_info_argc, ci->dev_info_argv,
122  NULL);
123 
124  if (dev_info_len > CUSE_INIT_INFO_MAX) {
125  fprintf(stderr, "cuse: dev_info (%zu) too large, limit=%u\n",
126  dev_info_len, CUSE_INIT_INFO_MAX);
127  return NULL;
128  }
129 
130  cd = calloc(1, sizeof(*cd) + dev_info_len);
131  if (!cd) {
132  fprintf(stderr, "cuse: failed to allocate cuse_data\n");
133  return NULL;
134  }
135 
136  memcpy(&cd->clop, clop, sizeof(cd->clop));
137  cd->max_read = 131072;
138  cd->dev_major = ci->dev_major;
139  cd->dev_minor = ci->dev_minor;
140  cd->dev_info_len = dev_info_len;
141  cd->flags = ci->flags;
142  cuse_pack_info(ci->dev_info_argc, ci->dev_info_argv, cd->dev_info);
143 
144  return cd;
145 }
146 
147 struct fuse_session *cuse_lowlevel_new(struct fuse_args *args,
148  const struct cuse_info *ci,
149  const struct cuse_lowlevel_ops *clop,
150  void *userdata)
151 {
152  struct fuse_lowlevel_ops lop;
153  struct cuse_data *cd;
154  struct fuse_session *se;
155 
156  cd = cuse_prep_data(ci, clop);
157  if (!cd)
158  return NULL;
159 
160  memset(&lop, 0, sizeof(lop));
161  lop.init = clop->init;
162  lop.destroy = clop->destroy;
163  lop.open = clop->open ? cuse_fll_open : NULL;
164  lop.read = clop->read ? cuse_fll_read : NULL;
165  lop.write = clop->write ? cuse_fll_write : NULL;
166  lop.flush = clop->flush ? cuse_fll_flush : NULL;
167  lop.release = clop->release ? cuse_fll_release : NULL;
168  lop.fsync = clop->fsync ? cuse_fll_fsync : NULL;
169  lop.ioctl = clop->ioctl ? cuse_fll_ioctl : NULL;
170  lop.poll = clop->poll ? cuse_fll_poll : NULL;
171 
172  se = fuse_session_new(args, &lop, sizeof(lop), userdata);
173  if (!se) {
174  free(cd);
175  return NULL;
176  }
177  se->cuse_data = cd;
178 
179  return se;
180 }
181 
182 static int cuse_reply_init(fuse_req_t req, struct cuse_init_out *arg,
183  char *dev_info, unsigned dev_info_len)
184 {
185  struct iovec iov[3];
186 
187  iov[1].iov_base = arg;
188  iov[1].iov_len = sizeof(struct cuse_init_out);
189  iov[2].iov_base = dev_info;
190  iov[2].iov_len = dev_info_len;
191 
192  return fuse_send_reply_iov_nofree(req, 0, iov, 3);
193 }
194 
195 void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
196 {
197  struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
198  struct cuse_init_out outarg;
199  struct fuse_session *se = req->se;
200  struct cuse_data *cd = se->cuse_data;
201  size_t bufsize = se->bufsize;
202  struct cuse_lowlevel_ops *clop = req_clop(req);
203 
204  (void) nodeid;
205  if (se->debug) {
206  fprintf(stderr, "CUSE_INIT: %u.%u\n", arg->major, arg->minor);
207  fprintf(stderr, "flags=0x%08x\n", arg->flags);
208  }
209  se->conn.proto_major = arg->major;
210  se->conn.proto_minor = arg->minor;
211  se->conn.capable = 0;
212  se->conn.want = 0;
213 
214  if (arg->major < 7) {
215  fprintf(stderr, "cuse: unsupported protocol version: %u.%u\n",
216  arg->major, arg->minor);
217  fuse_reply_err(req, EPROTO);
218  return;
219  }
220 
221  if (bufsize < FUSE_MIN_READ_BUFFER) {
222  fprintf(stderr, "cuse: warning: buffer size too small: %zu\n",
223  bufsize);
224  bufsize = FUSE_MIN_READ_BUFFER;
225  }
226 
227  bufsize -= 4096;
228  if (bufsize < se->conn.max_write)
229  se->conn.max_write = bufsize;
230 
231  se->got_init = 1;
232  if (se->op.init)
233  se->op.init(se->userdata, &se->conn);
234 
235  memset(&outarg, 0, sizeof(outarg));
236  outarg.major = FUSE_KERNEL_VERSION;
237  outarg.minor = FUSE_KERNEL_MINOR_VERSION;
238  outarg.flags = cd->flags;
239  outarg.max_read = cd->max_read;
240  outarg.max_write = se->conn.max_write;
241  outarg.dev_major = cd->dev_major;
242  outarg.dev_minor = cd->dev_minor;
243 
244  if (se->debug) {
245  fprintf(stderr, " CUSE_INIT: %u.%u\n",
246  outarg.major, outarg.minor);
247  fprintf(stderr, " flags=0x%08x\n", outarg.flags);
248  fprintf(stderr, " max_read=0x%08x\n", outarg.max_read);
249  fprintf(stderr, " max_write=0x%08x\n", outarg.max_write);
250  fprintf(stderr, " dev_major=%u\n", outarg.dev_major);
251  fprintf(stderr, " dev_minor=%u\n", outarg.dev_minor);
252  fprintf(stderr, " dev_info: %.*s\n", cd->dev_info_len,
253  cd->dev_info);
254  }
255 
256  cuse_reply_init(req, &outarg, cd->dev_info, cd->dev_info_len);
257 
258  if (clop->init_done)
259  clop->init_done(se->userdata);
260 
261  fuse_free_req(req);
262 }
263 
264 struct fuse_session *cuse_lowlevel_setup(int argc, char *argv[],
265  const struct cuse_info *ci,
266  const struct cuse_lowlevel_ops *clop,
267  int *multithreaded, void *userdata)
268 {
269  const char *devname = "/dev/cuse";
270  static const struct fuse_opt kill_subtype_opts[] = {
271  FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_DISCARD),
273  };
274  struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
275  struct fuse_session *se;
276  struct fuse_cmdline_opts opts;
277  int fd;
278  int res;
279 
280  if (fuse_parse_cmdline(&args, &opts) == -1)
281  return NULL;
282  *multithreaded = !opts.singlethread;
283 
284  /* Remove subtype= option */
285  res = fuse_opt_parse(&args, NULL, kill_subtype_opts, NULL);
286  if (res == -1)
287  goto out1;
288 
289  /*
290  * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
291  * would ensue.
292  */
293  do {
294  fd = open("/dev/null", O_RDWR);
295  if (fd > 2)
296  close(fd);
297  } while (fd >= 0 && fd <= 2);
298 
299  se = cuse_lowlevel_new(&args, ci, clop, userdata);
300  if (se == NULL)
301  goto out1;
302 
303  fd = open(devname, O_RDWR);
304  if (fd == -1) {
305  if (errno == ENODEV || errno == ENOENT)
306  fprintf(stderr, "cuse: device not found, try 'modprobe cuse' first\n");
307  else
308  fprintf(stderr, "cuse: failed to open %s: %s\n",
309  devname, strerror(errno));
310  goto err_se;
311  }
312  se->fd = fd;
313 
314  res = fuse_set_signal_handlers(se);
315  if (res == -1)
316  goto err_se;
317 
318  res = fuse_daemonize(opts.foreground);
319  if (res == -1)
320  goto err_sig;
321 
322  return se;
323 
324 err_sig:
326 err_se:
328 out1:
329  free(opts.mountpoint);
330  fuse_opt_free_args(&args);
331  return NULL;
332 }
333 
334 void cuse_lowlevel_teardown(struct fuse_session *se)
335 {
338 }
339 
340 int cuse_lowlevel_main(int argc, char *argv[], const struct cuse_info *ci,
341  const struct cuse_lowlevel_ops *clop, void *userdata)
342 {
343  struct fuse_session *se;
344  int multithreaded;
345  int res;
346 
347  se = cuse_lowlevel_setup(argc, argv, ci, clop, &multithreaded,
348  userdata);
349  if (se == NULL)
350  return 1;
351 
352  if (multithreaded) {
353  struct fuse_loop_config config;
354  config.clone_fd = 0;
355  config.max_idle_threads = 10;
356  res = fuse_session_loop_mt_32(se, &config);
357  }
358  else
359  res = fuse_session_loop(se);
360 
361  cuse_lowlevel_teardown(se);
362  if (res == -1)
363  return 1;
364 
365  return 0;
366 }
void fuse_session_destroy(struct fuse_session *se)
+
int fuse_reply_err(fuse_req_t req, int err)
+
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
+
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
+
int fuse_daemonize(int foreground)
Definition: helper.c:225
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
+
int fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts)
Definition: helper.c:202
+
int fuse_set_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:62
+
void fuse_remove_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:79
+
#define FUSE_OPT_KEY_DISCARD
Definition: fuse_opt.h:153
+ + +
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:33
+ +
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98
+
#define FUSE_OPT_END
Definition: fuse_opt.h:104
+
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
+ + + +
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
+ +
+ + + + diff --git a/doc/html/cuse__lowlevel_8h_source.html b/doc/html/cuse__lowlevel_8h_source.html new file mode 100644 index 0000000..37d0e18 --- /dev/null +++ b/doc/html/cuse__lowlevel_8h_source.html @@ -0,0 +1,63 @@ + + + + + + + +libfuse: include/cuse_lowlevel.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
cuse_lowlevel.h
+
+
+
1 /*
2  CUSE: Character device in Userspace
3  Copyright (C) 2008-2009 SUSE Linux Products GmbH
4  Copyright (C) 2008-2009 Tejun Heo <tj@kernel.org>
5 
6  This program can be distributed under the terms of the GNU LGPLv2.
7  See the file COPYING.LIB.
8 
9  Read example/cusexmp.c for usages.
10 */
11 
12 #ifndef CUSE_LOWLEVEL_H_
13 #define CUSE_LOWLEVEL_H_
14 
15 #ifndef FUSE_USE_VERSION
16 #define FUSE_USE_VERSION 29
17 #endif
18 
19 #include "fuse_lowlevel.h"
20 
21 #include <fcntl.h>
22 #include <sys/types.h>
23 #include <sys/uio.h>
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #define CUSE_UNRESTRICTED_IOCTL (1 << 0) /* use unrestricted ioctl */
30 
31 struct fuse_session;
32 
33 struct cuse_info {
34  unsigned dev_major;
35  unsigned dev_minor;
36  unsigned dev_info_argc;
37  const char **dev_info_argv;
38  unsigned flags;
39 };
40 
41 /*
42  * Most ops behave almost identically to the matching fuse_lowlevel
43  * ops except that they don't take @ino.
44  *
45  * init_done : called after initialization is complete
46  * read/write : always direct IO, simultaneous operations allowed
47  * ioctl : might be in unrestricted mode depending on ci->flags
48  */
49 struct cuse_lowlevel_ops {
50  void (*init) (void *userdata, struct fuse_conn_info *conn);
51  void (*init_done) (void *userdata);
52  void (*destroy) (void *userdata);
53  void (*open) (fuse_req_t req, struct fuse_file_info *fi);
54  void (*read) (fuse_req_t req, size_t size, off_t off,
55  struct fuse_file_info *fi);
56  void (*write) (fuse_req_t req, const char *buf, size_t size, off_t off,
57  struct fuse_file_info *fi);
58  void (*flush) (fuse_req_t req, struct fuse_file_info *fi);
59  void (*release) (fuse_req_t req, struct fuse_file_info *fi);
60  void (*fsync) (fuse_req_t req, int datasync, struct fuse_file_info *fi);
61  void (*ioctl) (fuse_req_t req, int cmd, void *arg,
62  struct fuse_file_info *fi, unsigned int flags,
63  const void *in_buf, size_t in_bufsz, size_t out_bufsz);
64  void (*poll) (fuse_req_t req, struct fuse_file_info *fi,
65  struct fuse_pollhandle *ph);
66 };
67 
68 struct fuse_session *cuse_lowlevel_new(struct fuse_args *args,
69  const struct cuse_info *ci,
70  const struct cuse_lowlevel_ops *clop,
71  void *userdata);
72 
73 struct fuse_session *cuse_lowlevel_setup(int argc, char *argv[],
74  const struct cuse_info *ci,
75  const struct cuse_lowlevel_ops *clop,
76  int *multithreaded, void *userdata);
77 
78 void cuse_lowlevel_teardown(struct fuse_session *se);
79 
80 int cuse_lowlevel_main(int argc, char *argv[], const struct cuse_info *ci,
81  const struct cuse_lowlevel_ops *clop, void *userdata);
82 
83 #ifdef __cplusplus
84 }
85 #endif
86 
87 #endif /* CUSE_LOWLEVEL_H_ */
+
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
+ + +
unsigned int flush
Definition: fuse_common.h:56
+ + +
+ + + + diff --git a/doc/html/dir_13e138d54eb8818da29c3992edef070a.html b/doc/html/dir_13e138d54eb8818da29c3992edef070a.html new file mode 100644 index 0000000..a7ce485 --- /dev/null +++ b/doc/html/dir_13e138d54eb8818da29c3992edef070a.html @@ -0,0 +1,56 @@ + + + + + + + +libfuse: test Directory Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
test Directory Reference
+
+
+
+ + + + diff --git a/doc/html/dir_23ec12649285f9fabf3a6b7380226c28.html b/doc/html/dir_23ec12649285f9fabf3a6b7380226c28.html new file mode 100644 index 0000000..99159c4 --- /dev/null +++ b/doc/html/dir_23ec12649285f9fabf3a6b7380226c28.html @@ -0,0 +1,56 @@ + + + + + + + +libfuse: util Directory Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
util Directory Reference
+
+
+
+ + + + diff --git a/doc/html/dir_4fef79e7177ba769987a8da36c892c5f.html b/doc/html/dir_4fef79e7177ba769987a8da36c892c5f.html new file mode 100644 index 0000000..41168ef --- /dev/null +++ b/doc/html/dir_4fef79e7177ba769987a8da36c892c5f.html @@ -0,0 +1,60 @@ + + + + + + + +libfuse: build Directory Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
build Directory Reference
+
+
+ + +

+Directories

+
+ + + + diff --git a/doc/html/dir_93598ca166e67dcc8cf3dfff647b911b.html b/doc/html/dir_93598ca166e67dcc8cf3dfff647b911b.html new file mode 100644 index 0000000..28e5554 --- /dev/null +++ b/doc/html/dir_93598ca166e67dcc8cf3dfff647b911b.html @@ -0,0 +1,56 @@ + + + + + + + +libfuse: build/meson-private Directory Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
meson-private Directory Reference
+
+
+
+ + + + diff --git a/doc/html/dir_97aefd0d527b934f1d99a682da8fe6a9.html b/doc/html/dir_97aefd0d527b934f1d99a682da8fe6a9.html new file mode 100644 index 0000000..6c3117c --- /dev/null +++ b/doc/html/dir_97aefd0d527b934f1d99a682da8fe6a9.html @@ -0,0 +1,60 @@ + + + + + + + +libfuse: lib Directory Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
lib Directory Reference
+
+
+ + +

+Directories

+
+ + + + diff --git a/doc/html/dir_cfafba98a580ce4b62f8a6fa96d7cbb0.html b/doc/html/dir_cfafba98a580ce4b62f8a6fa96d7cbb0.html new file mode 100644 index 0000000..80c0848 --- /dev/null +++ b/doc/html/dir_cfafba98a580ce4b62f8a6fa96d7cbb0.html @@ -0,0 +1,96 @@ + + + + + + + +libfuse: example Directory Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
example Directory Reference
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  cuse.c [code]
 
file  cuse_client.c [code]
 
file  hello.c [code]
 
file  hello_ll.c [code]
 
file  invalidate_path.c [code]
 
file  ioctl.c [code]
 
file  ioctl.h [code]
 
file  ioctl_client.c [code]
 
file  notify_inval_entry.c [code]
 
file  notify_inval_inode.c [code]
 
file  notify_store_retrieve.c [code]
 
file  null.c [code]
 
file  passthrough.c [code]
 
file  passthrough_fh.c [code]
 
file  passthrough_ll.c [code]
 
file  poll.c [code]
 
file  poll_client.c [code]
 
file  printcap.c [code]
 
+
+ + + + diff --git a/doc/html/dir_d44c64559bbebec7f509842c48db8b23.html b/doc/html/dir_d44c64559bbebec7f509842c48db8b23.html new file mode 100644 index 0000000..9e617f4 --- /dev/null +++ b/doc/html/dir_d44c64559bbebec7f509842c48db8b23.html @@ -0,0 +1,68 @@ + + + + + + + +libfuse: include Directory Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
include Directory Reference
+
+
+ + + + + + + + + + +

+Files

file  fuse.h [code]
 
file  fuse_common.h [code]
 
file  fuse_lowlevel.h [code]
 
file  fuse_opt.h [code]
 
+
+ + + + diff --git a/doc/html/dir_e1dbc8ba94a86723d4c32227b7c46099.html b/doc/html/dir_e1dbc8ba94a86723d4c32227b7c46099.html new file mode 100644 index 0000000..7ceb153 --- /dev/null +++ b/doc/html/dir_e1dbc8ba94a86723d4c32227b7c46099.html @@ -0,0 +1,56 @@ + + + + + + + +libfuse: lib/modules Directory Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
modules Directory Reference
+
+
+
+ + + + diff --git a/doc/html/doc.png b/doc/html/doc.png new file mode 100644 index 0000000..17edabf Binary files /dev/null and b/doc/html/doc.png differ diff --git a/doc/html/doxygen.css b/doc/html/doxygen.css new file mode 100644 index 0000000..4f1ab91 --- /dev/null +++ b/doc/html/doxygen.css @@ -0,0 +1,1596 @@ +/* The standard CSS for doxygen 1.8.13 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +p.reference, p.definition { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: url('nav_f.png'); + background-repeat: repeat-x; + background-color: #E2E8F2; + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-color: #DFE5F1; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + +} + +.overload { + font-family: "courier new",courier,monospace; + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +/* +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTableHead tr { +} + +table.markdownTableBodyLeft td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft { + text-align: left +} + +th.markdownTableHeadRight { + text-align: right +} + +th.markdownTableHeadCenter { + text-align: center +} +*/ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + + +/* @end */ diff --git a/doc/html/doxygen.png b/doc/html/doxygen.png new file mode 100644 index 0000000..3ff17d8 Binary files /dev/null and b/doc/html/doxygen.png differ diff --git a/doc/html/fast17-vangoor.pdf b/doc/html/fast17-vangoor.pdf new file mode 100644 index 0000000..cef7237 Binary files /dev/null and b/doc/html/fast17-vangoor.pdf differ diff --git a/doc/html/files.html b/doc/html/files.html new file mode 100644 index 0000000..24ca377 --- /dev/null +++ b/doc/html/files.html @@ -0,0 +1,114 @@ + + + + + + + +libfuse: File List + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+
[detail level 123]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  build
  meson-private
 sanitycheckc.c
 config.h
  example
 cuse.c
 cuse_client.c
 hello.c
 hello_ll.c
 invalidate_path.c
 ioctl.c
 ioctl.h
 ioctl_client.c
 notify_inval_entry.c
 notify_inval_inode.c
 notify_store_retrieve.c
 null.c
 passthrough.c
 passthrough_fh.c
 passthrough_ll.c
 poll.c
 poll_client.c
 printcap.c
  include
 cuse_lowlevel.h
 fuse.h
 fuse_common.h
 fuse_kernel.h
 fuse_lowlevel.h
 fuse_opt.h
  lib
  modules
 iconv.c
 subdir.c
 buffer.c
 cuse_lowlevel.c
 fuse.c
 fuse_i.h
 fuse_loop.c
 fuse_loop_mt.c
 fuse_lowlevel.c
 fuse_misc.h
 fuse_opt.c
 fuse_signals.c
 helper.c
 mount.c
 mount_bsd.c
 mount_util.c
 mount_util.h
  test
 stracedecode.c
 test_setattr.c
 test_syscalls.c
 test_write_cache.c
 wrong_command.c
  util
 fusermount.c
 mount.fuse.c
+
+
+ + + + diff --git a/doc/html/folderclosed.png b/doc/html/folderclosed.png new file mode 100644 index 0000000..bb8ab35 Binary files /dev/null and b/doc/html/folderclosed.png differ diff --git a/doc/html/folderopen.png b/doc/html/folderopen.png new file mode 100644 index 0000000..d6c7f67 Binary files /dev/null and b/doc/html/folderopen.png differ diff --git a/doc/html/functions.html b/doc/html/functions.html new file mode 100644 index 0000000..e5b2cd4 --- /dev/null +++ b/doc/html/functions.html @@ -0,0 +1,509 @@ + + + + + + + +libfuse: Data Fields + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- k -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+ + +

- w -

+
+ + + + diff --git a/doc/html/functions_vars.html b/doc/html/functions_vars.html new file mode 100644 index 0000000..0e061b5 --- /dev/null +++ b/doc/html/functions_vars.html @@ -0,0 +1,509 @@ + + + + + + + +libfuse: Data Fields - Variables + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+  + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- k -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+ + +

- w -

+
+ + + + diff --git a/doc/html/fuse_8c_source.html b/doc/html/fuse_8c_source.html new file mode 100644 index 0000000..6393b26 --- /dev/null +++ b/doc/html/fuse_8c_source.html @@ -0,0 +1,180 @@ + + + + + + + +libfuse: lib/fuse.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse.c
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Implementation of the high-level FUSE API on top of the low-level
6  API.
7 
8  This program can be distributed under the terms of the GNU LGPLv2.
9  See the file COPYING.LIB
10 */
11 
12 
13 /* For pthread_rwlock_t */
14 #define _GNU_SOURCE
15 
16 #include "config.h"
17 #include "fuse_i.h"
18 #include "fuse_lowlevel.h"
19 #include "fuse_opt.h"
20 #include "fuse_misc.h"
21 #include "fuse_kernel.h"
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <stddef.h>
27 #include <stdbool.h>
28 #include <unistd.h>
29 #include <time.h>
30 #include <fcntl.h>
31 #include <limits.h>
32 #include <errno.h>
33 #include <signal.h>
34 #include <dlfcn.h>
35 #include <assert.h>
36 #include <poll.h>
37 #include <sys/param.h>
38 #include <sys/uio.h>
39 #include <sys/time.h>
40 #include <sys/mman.h>
41 #include <sys/file.h>
42 
43 #define FUSE_NODE_SLAB 1
44 
45 #ifndef MAP_ANONYMOUS
46 #undef FUSE_NODE_SLAB
47 #endif
48 
49 #ifndef RENAME_EXCHANGE
50 #define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
51 #endif
52 
53 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
54 
55 #define FUSE_UNKNOWN_INO 0xffffffff
56 #define OFFSET_MAX 0x7fffffffffffffffLL
57 
58 #define NODE_TABLE_MIN_SIZE 8192
59 
60 struct fuse_fs {
61  struct fuse_operations op;
62  struct fuse_module *m;
63  void *user_data;
64  int debug;
65 };
66 
67 struct fusemod_so {
68  void *handle;
69  int ctr;
70 };
71 
72 struct lock_queue_element {
73  struct lock_queue_element *next;
74  pthread_cond_t cond;
75  fuse_ino_t nodeid1;
76  const char *name1;
77  char **path1;
78  struct node **wnode1;
79  fuse_ino_t nodeid2;
80  const char *name2;
81  char **path2;
82  struct node **wnode2;
83  int err;
84  bool first_locked : 1;
85  bool second_locked : 1;
86  bool done : 1;
87 };
88 
89 struct node_table {
90  struct node **array;
91  size_t use;
92  size_t size;
93  size_t split;
94 };
95 
96 #define container_of(ptr, type, member) ({ \
97  const typeof( ((type *)0)->member ) *__mptr = (ptr); \
98  (type *)( (char *)__mptr - offsetof(type,member) );})
99 
100 #define list_entry(ptr, type, member) \
101  container_of(ptr, type, member)
102 
103 struct list_head {
104  struct list_head *next;
105  struct list_head *prev;
106 };
107 
108 struct node_slab {
109  struct list_head list; /* must be the first member */
110  struct list_head freelist;
111  int used;
112 };
113 
114 struct fuse {
115  struct fuse_session *se;
116  struct node_table name_table;
117  struct node_table id_table;
118  struct list_head lru_table;
119  fuse_ino_t ctr;
120  unsigned int generation;
121  unsigned int hidectr;
122  pthread_mutex_t lock;
123  struct fuse_config conf;
124  int intr_installed;
125  struct fuse_fs *fs;
126  struct lock_queue_element *lockq;
127  int pagesize;
128  struct list_head partial_slabs;
129  struct list_head full_slabs;
130  pthread_t prune_thread;
131 };
132 
133 struct lock {
134  int type;
135  off_t start;
136  off_t end;
137  pid_t pid;
138  uint64_t owner;
139  struct lock *next;
140 };
141 
142 struct node {
143  struct node *name_next;
144  struct node *id_next;
145  fuse_ino_t nodeid;
146  unsigned int generation;
147  int refctr;
148  struct node *parent;
149  char *name;
150  uint64_t nlookup;
151  int open_count;
152  struct timespec stat_updated;
153  struct timespec mtime;
154  off_t size;
155  struct lock *locks;
156  unsigned int is_hidden : 1;
157  unsigned int cache_valid : 1;
158  int treelock;
159  char inline_name[32];
160 };
161 
162 #define TREELOCK_WRITE -1
163 #define TREELOCK_WAIT_OFFSET INT_MIN
164 
165 struct node_lru {
166  struct node node;
167  struct list_head lru;
168  struct timespec forget_time;
169 };
170 
171 struct fuse_direntry {
172  struct stat stat;
173  char *name;
174  struct fuse_direntry *next;
175 };
176 
177 struct fuse_dh {
178  pthread_mutex_t lock;
179  struct fuse *fuse;
180  fuse_req_t req;
181  char *contents;
182  struct fuse_direntry *first;
183  struct fuse_direntry **last;
184  unsigned len;
185  unsigned size;
186  unsigned needlen;
187  int filled;
188  uint64_t fh;
189  int error;
190  fuse_ino_t nodeid;
191 };
192 
193 struct fuse_context_i {
194  struct fuse_context ctx;
195  fuse_req_t req;
196 };
197 
198 /* Defined by FUSE_REGISTER_MODULE() in lib/modules/subdir.c and iconv.c. */
199 extern fuse_module_factory_t fuse_module_subdir_factory;
200 #ifdef HAVE_ICONV
201 extern fuse_module_factory_t fuse_module_iconv_factory;
202 #endif
203 
204 static pthread_key_t fuse_context_key;
205 static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
206 static int fuse_context_ref;
207 static struct fuse_module *fuse_modules = NULL;
208 
209 static int fuse_register_module(const char *name,
210  fuse_module_factory_t factory,
211  struct fusemod_so *so)
212 {
213  struct fuse_module *mod;
214 
215  mod = calloc(1, sizeof(struct fuse_module));
216  if (!mod) {
217  fprintf(stderr, "fuse: failed to allocate module\n");
218  return -1;
219  }
220  mod->name = strdup(name);
221  if (!mod->name) {
222  fprintf(stderr, "fuse: failed to allocate module name\n");
223  free(mod);
224  return -1;
225  }
226  mod->factory = factory;
227  mod->ctr = 0;
228  mod->so = so;
229  if (mod->so)
230  mod->so->ctr++;
231  mod->next = fuse_modules;
232  fuse_modules = mod;
233 
234  return 0;
235 }
236 
237 static void fuse_unregister_module(struct fuse_module *m)
238 {
239  struct fuse_module **mp;
240  for (mp = &fuse_modules; *mp; mp = &(*mp)->next) {
241  if (*mp == m) {
242  *mp = (*mp)->next;
243  break;
244  }
245  }
246  free(m->name);
247  free(m);
248 }
249 
250 static int fuse_load_so_module(const char *module)
251 {
252  int ret = -1;
253  char *tmp;
254  struct fusemod_so *so;
255  fuse_module_factory_t factory;
256 
257  tmp = malloc(strlen(module) + 64);
258  if (!tmp) {
259  fprintf(stderr, "fuse: memory allocation failed\n");
260  return -1;
261  }
262  sprintf(tmp, "libfusemod_%s.so", module);
263  so = calloc(1, sizeof(struct fusemod_so));
264  if (!so) {
265  fprintf(stderr, "fuse: failed to allocate module so\n");
266  goto out;
267  }
268 
269  so->handle = dlopen(tmp, RTLD_NOW);
270  if (so->handle == NULL) {
271  fprintf(stderr, "fuse: dlopen(%s) failed: %s\n",
272  tmp, dlerror());
273  goto out_free_so;
274  }
275 
276  sprintf(tmp, "fuse_module_%s_factory", module);
277  *(void**)(&factory) = dlsym(so->handle, tmp);
278  if (factory == NULL) {
279  fprintf(stderr, "fuse: symbol <%s> not found in module: %s\n",
280  tmp, dlerror());
281  goto out_dlclose;
282  }
283  ret = fuse_register_module(module, factory, so);
284  if (ret)
285  goto out_dlclose;
286 
287 out:
288  free(tmp);
289  return ret;
290 
291 out_dlclose:
292  dlclose(so->handle);
293 out_free_so:
294  free(so);
295  goto out;
296 }
297 
298 static struct fuse_module *fuse_find_module(const char *module)
299 {
300  struct fuse_module *m;
301  for (m = fuse_modules; m; m = m->next) {
302  if (strcmp(module, m->name) == 0) {
303  m->ctr++;
304  break;
305  }
306  }
307  return m;
308 }
309 
310 static struct fuse_module *fuse_get_module(const char *module)
311 {
312  struct fuse_module *m;
313 
314  pthread_mutex_lock(&fuse_context_lock);
315  m = fuse_find_module(module);
316  if (!m) {
317  int err = fuse_load_so_module(module);
318  if (!err)
319  m = fuse_find_module(module);
320  }
321  pthread_mutex_unlock(&fuse_context_lock);
322  return m;
323 }
324 
325 static void fuse_put_module(struct fuse_module *m)
326 {
327  pthread_mutex_lock(&fuse_context_lock);
328  if (m->so)
329  assert(m->ctr > 0);
330  /* Builtin modules may already have m->ctr == 0 */
331  if (m->ctr > 0)
332  m->ctr--;
333  if (!m->ctr && m->so) {
334  struct fusemod_so *so = m->so;
335  assert(so->ctr > 0);
336  so->ctr--;
337  if (!so->ctr) {
338  struct fuse_module **mp;
339  for (mp = &fuse_modules; *mp;) {
340  if ((*mp)->so == so)
341  fuse_unregister_module(*mp);
342  else
343  mp = &(*mp)->next;
344  }
345  dlclose(so->handle);
346  free(so);
347  }
348  } else if (!m->ctr) {
349  fuse_unregister_module(m);
350  }
351  pthread_mutex_unlock(&fuse_context_lock);
352 }
353 
354 static void init_list_head(struct list_head *list)
355 {
356  list->next = list;
357  list->prev = list;
358 }
359 
360 static int list_empty(const struct list_head *head)
361 {
362  return head->next == head;
363 }
364 
365 static void list_add(struct list_head *new, struct list_head *prev,
366  struct list_head *next)
367 {
368  next->prev = new;
369  new->next = next;
370  new->prev = prev;
371  prev->next = new;
372 }
373 
374 static inline void list_add_head(struct list_head *new, struct list_head *head)
375 {
376  list_add(new, head, head->next);
377 }
378 
379 static inline void list_add_tail(struct list_head *new, struct list_head *head)
380 {
381  list_add(new, head->prev, head);
382 }
383 
384 static inline void list_del(struct list_head *entry)
385 {
386  struct list_head *prev = entry->prev;
387  struct list_head *next = entry->next;
388 
389  next->prev = prev;
390  prev->next = next;
391 }
392 
393 static inline int lru_enabled(struct fuse *f)
394 {
395  return f->conf.remember > 0;
396 }
397 
398 static struct node_lru *node_lru(struct node *node)
399 {
400  return (struct node_lru *) node;
401 }
402 
403 static size_t get_node_size(struct fuse *f)
404 {
405  if (lru_enabled(f))
406  return sizeof(struct node_lru);
407  else
408  return sizeof(struct node);
409 }
410 
411 #ifdef FUSE_NODE_SLAB
412 static struct node_slab *list_to_slab(struct list_head *head)
413 {
414  return (struct node_slab *) head;
415 }
416 
417 static struct node_slab *node_to_slab(struct fuse *f, struct node *node)
418 {
419  return (struct node_slab *) (((uintptr_t) node) & ~((uintptr_t) f->pagesize - 1));
420 }
421 
422 static int alloc_slab(struct fuse *f)
423 {
424  void *mem;
425  struct node_slab *slab;
426  char *start;
427  size_t num;
428  size_t i;
429  size_t node_size = get_node_size(f);
430 
431  mem = mmap(NULL, f->pagesize, PROT_READ | PROT_WRITE,
432  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
433 
434  if (mem == MAP_FAILED)
435  return -1;
436 
437  slab = mem;
438  init_list_head(&slab->freelist);
439  slab->used = 0;
440  num = (f->pagesize - sizeof(struct node_slab)) / node_size;
441 
442  start = (char *) mem + f->pagesize - num * node_size;
443  for (i = 0; i < num; i++) {
444  struct list_head *n;
445 
446  n = (struct list_head *) (start + i * node_size);
447  list_add_tail(n, &slab->freelist);
448  }
449  list_add_tail(&slab->list, &f->partial_slabs);
450 
451  return 0;
452 }
453 
454 static struct node *alloc_node(struct fuse *f)
455 {
456  struct node_slab *slab;
457  struct list_head *node;
458 
459  if (list_empty(&f->partial_slabs)) {
460  int res = alloc_slab(f);
461  if (res != 0)
462  return NULL;
463  }
464  slab = list_to_slab(f->partial_slabs.next);
465  slab->used++;
466  node = slab->freelist.next;
467  list_del(node);
468  if (list_empty(&slab->freelist)) {
469  list_del(&slab->list);
470  list_add_tail(&slab->list, &f->full_slabs);
471  }
472  memset(node, 0, sizeof(struct node));
473 
474  return (struct node *) node;
475 }
476 
477 static void free_slab(struct fuse *f, struct node_slab *slab)
478 {
479  int res;
480 
481  list_del(&slab->list);
482  res = munmap(slab, f->pagesize);
483  if (res == -1)
484  fprintf(stderr, "fuse warning: munmap(%p) failed\n", slab);
485 }
486 
487 static void free_node_mem(struct fuse *f, struct node *node)
488 {
489  struct node_slab *slab = node_to_slab(f, node);
490  struct list_head *n = (struct list_head *) node;
491 
492  slab->used--;
493  if (slab->used) {
494  if (list_empty(&slab->freelist)) {
495  list_del(&slab->list);
496  list_add_tail(&slab->list, &f->partial_slabs);
497  }
498  list_add_head(n, &slab->freelist);
499  } else {
500  free_slab(f, slab);
501  }
502 }
503 #else
504 static struct node *alloc_node(struct fuse *f)
505 {
506  return (struct node *) calloc(1, get_node_size(f));
507 }
508 
509 static void free_node_mem(struct fuse *f, struct node *node)
510 {
511  (void) f;
512  free(node);
513 }
514 #endif
515 
516 static size_t id_hash(struct fuse *f, fuse_ino_t ino)
517 {
518  uint64_t hash = ((uint32_t) ino * 2654435761U) % f->id_table.size;
519  uint64_t oldhash = hash % (f->id_table.size / 2);
520 
521  if (oldhash >= f->id_table.split)
522  return oldhash;
523  else
524  return hash;
525 }
526 
527 static struct node *get_node_nocheck(struct fuse *f, fuse_ino_t nodeid)
528 {
529  size_t hash = id_hash(f, nodeid);
530  struct node *node;
531 
532  for (node = f->id_table.array[hash]; node != NULL; node = node->id_next)
533  if (node->nodeid == nodeid)
534  return node;
535 
536  return NULL;
537 }
538 
539 static struct node *get_node(struct fuse *f, fuse_ino_t nodeid)
540 {
541  struct node *node = get_node_nocheck(f, nodeid);
542  if (!node) {
543  fprintf(stderr, "fuse internal error: node %llu not found\n",
544  (unsigned long long) nodeid);
545  abort();
546  }
547  return node;
548 }
549 
550 static void curr_time(struct timespec *now);
551 static double diff_timespec(const struct timespec *t1,
552  const struct timespec *t2);
553 
554 static void remove_node_lru(struct node *node)
555 {
556  struct node_lru *lnode = node_lru(node);
557  list_del(&lnode->lru);
558  init_list_head(&lnode->lru);
559 }
560 
561 static void set_forget_time(struct fuse *f, struct node *node)
562 {
563  struct node_lru *lnode = node_lru(node);
564 
565  list_del(&lnode->lru);
566  list_add_tail(&lnode->lru, &f->lru_table);
567  curr_time(&lnode->forget_time);
568 }
569 
570 static void free_node(struct fuse *f, struct node *node)
571 {
572  if (node->name != node->inline_name)
573  free(node->name);
574  free_node_mem(f, node);
575 }
576 
577 static void node_table_reduce(struct node_table *t)
578 {
579  size_t newsize = t->size / 2;
580  void *newarray;
581 
582  if (newsize < NODE_TABLE_MIN_SIZE)
583  return;
584 
585  newarray = realloc(t->array, sizeof(struct node *) * newsize);
586  if (newarray != NULL)
587  t->array = newarray;
588 
589  t->size = newsize;
590  t->split = t->size / 2;
591 }
592 
593 static void remerge_id(struct fuse *f)
594 {
595  struct node_table *t = &f->id_table;
596  int iter;
597 
598  if (t->split == 0)
599  node_table_reduce(t);
600 
601  for (iter = 8; t->split > 0 && iter; iter--) {
602  struct node **upper;
603 
604  t->split--;
605  upper = &t->array[t->split + t->size / 2];
606  if (*upper) {
607  struct node **nodep;
608 
609  for (nodep = &t->array[t->split]; *nodep;
610  nodep = &(*nodep)->id_next);
611 
612  *nodep = *upper;
613  *upper = NULL;
614  break;
615  }
616  }
617 }
618 
619 static void unhash_id(struct fuse *f, struct node *node)
620 {
621  struct node **nodep = &f->id_table.array[id_hash(f, node->nodeid)];
622 
623  for (; *nodep != NULL; nodep = &(*nodep)->id_next)
624  if (*nodep == node) {
625  *nodep = node->id_next;
626  f->id_table.use--;
627 
628  if(f->id_table.use < f->id_table.size / 4)
629  remerge_id(f);
630  return;
631  }
632 }
633 
634 static int node_table_resize(struct node_table *t)
635 {
636  size_t newsize = t->size * 2;
637  void *newarray;
638 
639  newarray = realloc(t->array, sizeof(struct node *) * newsize);
640  if (newarray == NULL)
641  return -1;
642 
643  t->array = newarray;
644  memset(t->array + t->size, 0, t->size * sizeof(struct node *));
645  t->size = newsize;
646  t->split = 0;
647 
648  return 0;
649 }
650 
651 static void rehash_id(struct fuse *f)
652 {
653  struct node_table *t = &f->id_table;
654  struct node **nodep;
655  struct node **next;
656  size_t hash;
657 
658  if (t->split == t->size / 2)
659  return;
660 
661  hash = t->split;
662  t->split++;
663  for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
664  struct node *node = *nodep;
665  size_t newhash = id_hash(f, node->nodeid);
666 
667  if (newhash != hash) {
668  next = nodep;
669  *nodep = node->id_next;
670  node->id_next = t->array[newhash];
671  t->array[newhash] = node;
672  } else {
673  next = &node->id_next;
674  }
675  }
676  if (t->split == t->size / 2)
677  node_table_resize(t);
678 }
679 
680 static void hash_id(struct fuse *f, struct node *node)
681 {
682  size_t hash = id_hash(f, node->nodeid);
683  node->id_next = f->id_table.array[hash];
684  f->id_table.array[hash] = node;
685  f->id_table.use++;
686 
687  if (f->id_table.use >= f->id_table.size / 2)
688  rehash_id(f);
689 }
690 
691 static size_t name_hash(struct fuse *f, fuse_ino_t parent,
692  const char *name)
693 {
694  uint64_t hash = parent;
695  uint64_t oldhash;
696 
697  for (; *name; name++)
698  hash = hash * 31 + (unsigned char) *name;
699 
700  hash %= f->name_table.size;
701  oldhash = hash % (f->name_table.size / 2);
702  if (oldhash >= f->name_table.split)
703  return oldhash;
704  else
705  return hash;
706 }
707 
708 static void unref_node(struct fuse *f, struct node *node);
709 
710 static void remerge_name(struct fuse *f)
711 {
712  struct node_table *t = &f->name_table;
713  int iter;
714 
715  if (t->split == 0)
716  node_table_reduce(t);
717 
718  for (iter = 8; t->split > 0 && iter; iter--) {
719  struct node **upper;
720 
721  t->split--;
722  upper = &t->array[t->split + t->size / 2];
723  if (*upper) {
724  struct node **nodep;
725 
726  for (nodep = &t->array[t->split]; *nodep;
727  nodep = &(*nodep)->name_next);
728 
729  *nodep = *upper;
730  *upper = NULL;
731  break;
732  }
733  }
734 }
735 
736 static void unhash_name(struct fuse *f, struct node *node)
737 {
738  if (node->name) {
739  size_t hash = name_hash(f, node->parent->nodeid, node->name);
740  struct node **nodep = &f->name_table.array[hash];
741 
742  for (; *nodep != NULL; nodep = &(*nodep)->name_next)
743  if (*nodep == node) {
744  *nodep = node->name_next;
745  node->name_next = NULL;
746  unref_node(f, node->parent);
747  if (node->name != node->inline_name)
748  free(node->name);
749  node->name = NULL;
750  node->parent = NULL;
751  f->name_table.use--;
752 
753  if (f->name_table.use < f->name_table.size / 4)
754  remerge_name(f);
755  return;
756  }
757  fprintf(stderr,
758  "fuse internal error: unable to unhash node: %llu\n",
759  (unsigned long long) node->nodeid);
760  abort();
761  }
762 }
763 
764 static void rehash_name(struct fuse *f)
765 {
766  struct node_table *t = &f->name_table;
767  struct node **nodep;
768  struct node **next;
769  size_t hash;
770 
771  if (t->split == t->size / 2)
772  return;
773 
774  hash = t->split;
775  t->split++;
776  for (nodep = &t->array[hash]; *nodep != NULL; nodep = next) {
777  struct node *node = *nodep;
778  size_t newhash = name_hash(f, node->parent->nodeid, node->name);
779 
780  if (newhash != hash) {
781  next = nodep;
782  *nodep = node->name_next;
783  node->name_next = t->array[newhash];
784  t->array[newhash] = node;
785  } else {
786  next = &node->name_next;
787  }
788  }
789  if (t->split == t->size / 2)
790  node_table_resize(t);
791 }
792 
793 static int hash_name(struct fuse *f, struct node *node, fuse_ino_t parentid,
794  const char *name)
795 {
796  size_t hash = name_hash(f, parentid, name);
797  struct node *parent = get_node(f, parentid);
798  if (strlen(name) < sizeof(node->inline_name)) {
799  strcpy(node->inline_name, name);
800  node->name = node->inline_name;
801  } else {
802  node->name = strdup(name);
803  if (node->name == NULL)
804  return -1;
805  }
806 
807  parent->refctr ++;
808  node->parent = parent;
809  node->name_next = f->name_table.array[hash];
810  f->name_table.array[hash] = node;
811  f->name_table.use++;
812 
813  if (f->name_table.use >= f->name_table.size / 2)
814  rehash_name(f);
815 
816  return 0;
817 }
818 
819 static void delete_node(struct fuse *f, struct node *node)
820 {
821  if (f->conf.debug)
822  fprintf(stderr, "DELETE: %llu\n",
823  (unsigned long long) node->nodeid);
824 
825  assert(node->treelock == 0);
826  unhash_name(f, node);
827  if (lru_enabled(f))
828  remove_node_lru(node);
829  unhash_id(f, node);
830  free_node(f, node);
831 }
832 
833 static void unref_node(struct fuse *f, struct node *node)
834 {
835  assert(node->refctr > 0);
836  node->refctr --;
837  if (!node->refctr)
838  delete_node(f, node);
839 }
840 
841 static fuse_ino_t next_id(struct fuse *f)
842 {
843  do {
844  f->ctr = (f->ctr + 1) & 0xffffffff;
845  if (!f->ctr)
846  f->generation ++;
847  } while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
848  get_node_nocheck(f, f->ctr) != NULL);
849  return f->ctr;
850 }
851 
852 static struct node *lookup_node(struct fuse *f, fuse_ino_t parent,
853  const char *name)
854 {
855  size_t hash = name_hash(f, parent, name);
856  struct node *node;
857 
858  for (node = f->name_table.array[hash]; node != NULL; node = node->name_next)
859  if (node->parent->nodeid == parent &&
860  strcmp(node->name, name) == 0)
861  return node;
862 
863  return NULL;
864 }
865 
866 static void inc_nlookup(struct node *node)
867 {
868  if (!node->nlookup)
869  node->refctr++;
870  node->nlookup++;
871 }
872 
873 static struct node *find_node(struct fuse *f, fuse_ino_t parent,
874  const char *name)
875 {
876  struct node *node;
877 
878  pthread_mutex_lock(&f->lock);
879  if (!name)
880  node = get_node(f, parent);
881  else
882  node = lookup_node(f, parent, name);
883  if (node == NULL) {
884  node = alloc_node(f);
885  if (node == NULL)
886  goto out_err;
887 
888  node->nodeid = next_id(f);
889  node->generation = f->generation;
890  if (f->conf.remember)
891  inc_nlookup(node);
892 
893  if (hash_name(f, node, parent, name) == -1) {
894  free_node(f, node);
895  node = NULL;
896  goto out_err;
897  }
898  hash_id(f, node);
899  if (lru_enabled(f)) {
900  struct node_lru *lnode = node_lru(node);
901  init_list_head(&lnode->lru);
902  }
903  } else if (lru_enabled(f) && node->nlookup == 1) {
904  remove_node_lru(node);
905  }
906  inc_nlookup(node);
907 out_err:
908  pthread_mutex_unlock(&f->lock);
909  return node;
910 }
911 
912 static int lookup_path_in_cache(struct fuse *f,
913  const char *path, fuse_ino_t *inop)
914 {
915  char *tmp = strdup(path);
916  if (!tmp)
917  return -ENOMEM;
918 
919  pthread_mutex_lock(&f->lock);
920  fuse_ino_t ino = FUSE_ROOT_ID;
921 
922  int err = 0;
923  char *save_ptr;
924  char *path_element = strtok_r(tmp, "/", &save_ptr);
925  while (path_element != NULL) {
926  struct node *node = lookup_node(f, ino, path_element);
927  if (node == NULL) {
928  err = -ENOENT;
929  break;
930  }
931  ino = node->nodeid;
932  path_element = strtok_r(NULL, "/", &save_ptr);
933  }
934  pthread_mutex_unlock(&f->lock);
935  free(tmp);
936 
937  if (!err)
938  *inop = ino;
939  return err;
940 }
941 
942 static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
943 {
944  size_t len = strlen(name);
945 
946  if (s - len <= *buf) {
947  unsigned pathlen = *bufsize - (s - *buf);
948  unsigned newbufsize = *bufsize;
949  char *newbuf;
950 
951  while (newbufsize < pathlen + len + 1) {
952  if (newbufsize >= 0x80000000)
953  newbufsize = 0xffffffff;
954  else
955  newbufsize *= 2;
956  }
957 
958  newbuf = realloc(*buf, newbufsize);
959  if (newbuf == NULL)
960  return NULL;
961 
962  *buf = newbuf;
963  s = newbuf + newbufsize - pathlen;
964  memmove(s, newbuf + *bufsize - pathlen, pathlen);
965  *bufsize = newbufsize;
966  }
967  s -= len;
968  strncpy(s, name, len);
969  s--;
970  *s = '/';
971 
972  return s;
973 }
974 
975 static void unlock_path(struct fuse *f, fuse_ino_t nodeid, struct node *wnode,
976  struct node *end)
977 {
978  struct node *node;
979 
980  if (wnode) {
981  assert(wnode->treelock == TREELOCK_WRITE);
982  wnode->treelock = 0;
983  }
984 
985  for (node = get_node(f, nodeid);
986  node != end && node->nodeid != FUSE_ROOT_ID; node = node->parent) {
987  assert(node->treelock != 0);
988  assert(node->treelock != TREELOCK_WAIT_OFFSET);
989  assert(node->treelock != TREELOCK_WRITE);
990  node->treelock--;
991  if (node->treelock == TREELOCK_WAIT_OFFSET)
992  node->treelock = 0;
993  }
994 }
995 
996 static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name,
997  char **path, struct node **wnodep, bool need_lock)
998 {
999  unsigned bufsize = 256;
1000  char *buf;
1001  char *s;
1002  struct node *node;
1003  struct node *wnode = NULL;
1004  int err;
1005 
1006  *path = NULL;
1007 
1008  err = -ENOMEM;
1009  buf = malloc(bufsize);
1010  if (buf == NULL)
1011  goto out_err;
1012 
1013  s = buf + bufsize - 1;
1014  *s = '\0';
1015 
1016  if (name != NULL) {
1017  s = add_name(&buf, &bufsize, s, name);
1018  err = -ENOMEM;
1019  if (s == NULL)
1020  goto out_free;
1021  }
1022 
1023  if (wnodep) {
1024  assert(need_lock);
1025  wnode = lookup_node(f, nodeid, name);
1026  if (wnode) {
1027  if (wnode->treelock != 0) {
1028  if (wnode->treelock > 0)
1029  wnode->treelock += TREELOCK_WAIT_OFFSET;
1030  err = -EAGAIN;
1031  goto out_free;
1032  }
1033  wnode->treelock = TREELOCK_WRITE;
1034  }
1035  }
1036 
1037  for (node = get_node(f, nodeid); node->nodeid != FUSE_ROOT_ID;
1038  node = node->parent) {
1039  err = -ENOENT;
1040  if (node->name == NULL || node->parent == NULL)
1041  goto out_unlock;
1042 
1043  err = -ENOMEM;
1044  s = add_name(&buf, &bufsize, s, node->name);
1045  if (s == NULL)
1046  goto out_unlock;
1047 
1048  if (need_lock) {
1049  err = -EAGAIN;
1050  if (node->treelock < 0)
1051  goto out_unlock;
1052 
1053  node->treelock++;
1054  }
1055  }
1056 
1057  if (s[0])
1058  memmove(buf, s, bufsize - (s - buf));
1059  else
1060  strcpy(buf, "/");
1061 
1062  *path = buf;
1063  if (wnodep)
1064  *wnodep = wnode;
1065 
1066  return 0;
1067 
1068  out_unlock:
1069  if (need_lock)
1070  unlock_path(f, nodeid, wnode, node);
1071  out_free:
1072  free(buf);
1073 
1074  out_err:
1075  return err;
1076 }
1077 
1078 static void queue_element_unlock(struct fuse *f, struct lock_queue_element *qe)
1079 {
1080  struct node *wnode;
1081 
1082  if (qe->first_locked) {
1083  wnode = qe->wnode1 ? *qe->wnode1 : NULL;
1084  unlock_path(f, qe->nodeid1, wnode, NULL);
1085  qe->first_locked = false;
1086  }
1087  if (qe->second_locked) {
1088  wnode = qe->wnode2 ? *qe->wnode2 : NULL;
1089  unlock_path(f, qe->nodeid2, wnode, NULL);
1090  qe->second_locked = false;
1091  }
1092 }
1093 
1094 static void queue_element_wakeup(struct fuse *f, struct lock_queue_element *qe)
1095 {
1096  int err;
1097  bool first = (qe == f->lockq);
1098 
1099  if (!qe->path1) {
1100  /* Just waiting for it to be unlocked */
1101  if (get_node(f, qe->nodeid1)->treelock == 0)
1102  pthread_cond_signal(&qe->cond);
1103 
1104  return;
1105  }
1106 
1107  if (!qe->first_locked) {
1108  err = try_get_path(f, qe->nodeid1, qe->name1, qe->path1,
1109  qe->wnode1, true);
1110  if (!err)
1111  qe->first_locked = true;
1112  else if (err != -EAGAIN)
1113  goto err_unlock;
1114  }
1115  if (!qe->second_locked && qe->path2) {
1116  err = try_get_path(f, qe->nodeid2, qe->name2, qe->path2,
1117  qe->wnode2, true);
1118  if (!err)
1119  qe->second_locked = true;
1120  else if (err != -EAGAIN)
1121  goto err_unlock;
1122  }
1123 
1124  if (qe->first_locked && (qe->second_locked || !qe->path2)) {
1125  err = 0;
1126  goto done;
1127  }
1128 
1129  /*
1130  * Only let the first element be partially locked otherwise there could
1131  * be a deadlock.
1132  *
1133  * But do allow the first element to be partially locked to prevent
1134  * starvation.
1135  */
1136  if (!first)
1137  queue_element_unlock(f, qe);
1138 
1139  /* keep trying */
1140  return;
1141 
1142 err_unlock:
1143  queue_element_unlock(f, qe);
1144 done:
1145  qe->err = err;
1146  qe->done = true;
1147  pthread_cond_signal(&qe->cond);
1148 }
1149 
1150 static void wake_up_queued(struct fuse *f)
1151 {
1152  struct lock_queue_element *qe;
1153 
1154  for (qe = f->lockq; qe != NULL; qe = qe->next)
1155  queue_element_wakeup(f, qe);
1156 }
1157 
1158 static void debug_path(struct fuse *f, const char *msg, fuse_ino_t nodeid,
1159  const char *name, bool wr)
1160 {
1161  if (f->conf.debug) {
1162  struct node *wnode = NULL;
1163 
1164  if (wr)
1165  wnode = lookup_node(f, nodeid, name);
1166 
1167  if (wnode) {
1168  fprintf(stderr, "%s %llu (w)\n",
1169  msg, (unsigned long long) wnode->nodeid);
1170  } else {
1171  fprintf(stderr, "%s %llu\n",
1172  msg, (unsigned long long) nodeid);
1173  }
1174  }
1175 }
1176 
1177 static void queue_path(struct fuse *f, struct lock_queue_element *qe)
1178 {
1179  struct lock_queue_element **qp;
1180 
1181  qe->done = false;
1182  qe->first_locked = false;
1183  qe->second_locked = false;
1184  pthread_cond_init(&qe->cond, NULL);
1185  qe->next = NULL;
1186  for (qp = &f->lockq; *qp != NULL; qp = &(*qp)->next);
1187  *qp = qe;
1188 }
1189 
1190 static void dequeue_path(struct fuse *f, struct lock_queue_element *qe)
1191 {
1192  struct lock_queue_element **qp;
1193 
1194  pthread_cond_destroy(&qe->cond);
1195  for (qp = &f->lockq; *qp != qe; qp = &(*qp)->next);
1196  *qp = qe->next;
1197 }
1198 
1199 static int wait_path(struct fuse *f, struct lock_queue_element *qe)
1200 {
1201  queue_path(f, qe);
1202 
1203  do {
1204  pthread_cond_wait(&qe->cond, &f->lock);
1205  } while (!qe->done);
1206 
1207  dequeue_path(f, qe);
1208 
1209  return qe->err;
1210 }
1211 
1212 static int get_path_common(struct fuse *f, fuse_ino_t nodeid, const char *name,
1213  char **path, struct node **wnode)
1214 {
1215  int err;
1216 
1217  pthread_mutex_lock(&f->lock);
1218  err = try_get_path(f, nodeid, name, path, wnode, true);
1219  if (err == -EAGAIN) {
1220  struct lock_queue_element qe = {
1221  .nodeid1 = nodeid,
1222  .name1 = name,
1223  .path1 = path,
1224  .wnode1 = wnode,
1225  };
1226  debug_path(f, "QUEUE PATH", nodeid, name, !!wnode);
1227  err = wait_path(f, &qe);
1228  debug_path(f, "DEQUEUE PATH", nodeid, name, !!wnode);
1229  }
1230  pthread_mutex_unlock(&f->lock);
1231 
1232  return err;
1233 }
1234 
1235 static int get_path(struct fuse *f, fuse_ino_t nodeid, char **path)
1236 {
1237  return get_path_common(f, nodeid, NULL, path, NULL);
1238 }
1239 
1240 static int get_path_nullok(struct fuse *f, fuse_ino_t nodeid, char **path)
1241 {
1242  int err = 0;
1243 
1244  if (f->conf.nullpath_ok) {
1245  *path = NULL;
1246  } else {
1247  err = get_path_common(f, nodeid, NULL, path, NULL);
1248  if (err == -ENOENT)
1249  err = 0;
1250  }
1251 
1252  return err;
1253 }
1254 
1255 static int get_path_name(struct fuse *f, fuse_ino_t nodeid, const char *name,
1256  char **path)
1257 {
1258  return get_path_common(f, nodeid, name, path, NULL);
1259 }
1260 
1261 static int get_path_wrlock(struct fuse *f, fuse_ino_t nodeid, const char *name,
1262  char **path, struct node **wnode)
1263 {
1264  return get_path_common(f, nodeid, name, path, wnode);
1265 }
1266 
1267 #if defined(__FreeBSD__)
1268 #define CHECK_DIR_LOOP
1269 #endif
1270 
1271 #if defined(CHECK_DIR_LOOP)
1272 static int check_dir_loop(struct fuse *f,
1273  fuse_ino_t nodeid1, const char *name1,
1274  fuse_ino_t nodeid2, const char *name2)
1275 {
1276  struct node *node, *node1, *node2;
1277  fuse_ino_t id1, id2;
1278 
1279  node1 = lookup_node(f, nodeid1, name1);
1280  id1 = node1 ? node1->nodeid : nodeid1;
1281 
1282  node2 = lookup_node(f, nodeid2, name2);
1283  id2 = node2 ? node2->nodeid : nodeid2;
1284 
1285  for (node = get_node(f, id2); node->nodeid != FUSE_ROOT_ID;
1286  node = node->parent) {
1287  if (node->name == NULL || node->parent == NULL)
1288  break;
1289 
1290  if (node->nodeid != id2 && node->nodeid == id1)
1291  return -EINVAL;
1292  }
1293 
1294  if (node2)
1295  {
1296  for (node = get_node(f, id1); node->nodeid != FUSE_ROOT_ID;
1297  node = node->parent) {
1298  if (node->name == NULL || node->parent == NULL)
1299  break;
1300 
1301  if (node->nodeid != id1 && node->nodeid == id2)
1302  return -ENOTEMPTY;
1303  }
1304  }
1305 
1306  return 0;
1307 }
1308 #endif
1309 
1310 static int try_get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
1311  fuse_ino_t nodeid2, const char *name2,
1312  char **path1, char **path2,
1313  struct node **wnode1, struct node **wnode2)
1314 {
1315  int err;
1316 
1317  /* FIXME: locking two paths needs deadlock checking */
1318  err = try_get_path(f, nodeid1, name1, path1, wnode1, true);
1319  if (!err) {
1320  err = try_get_path(f, nodeid2, name2, path2, wnode2, true);
1321  if (err) {
1322  struct node *wn1 = wnode1 ? *wnode1 : NULL;
1323 
1324  unlock_path(f, nodeid1, wn1, NULL);
1325  free(*path1);
1326  }
1327  }
1328  return err;
1329 }
1330 
1331 static int get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
1332  fuse_ino_t nodeid2, const char *name2,
1333  char **path1, char **path2,
1334  struct node **wnode1, struct node **wnode2)
1335 {
1336  int err;
1337 
1338  pthread_mutex_lock(&f->lock);
1339 
1340 #if defined(CHECK_DIR_LOOP)
1341  if (name1)
1342  {
1343  // called during rename; perform dir loop check
1344  err = check_dir_loop(f, nodeid1, name1, nodeid2, name2);
1345  if (err)
1346  goto out_unlock;
1347  }
1348 #endif
1349 
1350  err = try_get_path2(f, nodeid1, name1, nodeid2, name2,
1351  path1, path2, wnode1, wnode2);
1352  if (err == -EAGAIN) {
1353  struct lock_queue_element qe = {
1354  .nodeid1 = nodeid1,
1355  .name1 = name1,
1356  .path1 = path1,
1357  .wnode1 = wnode1,
1358  .nodeid2 = nodeid2,
1359  .name2 = name2,
1360  .path2 = path2,
1361  .wnode2 = wnode2,
1362  };
1363 
1364  debug_path(f, "QUEUE PATH1", nodeid1, name1, !!wnode1);
1365  debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
1366  err = wait_path(f, &qe);
1367  debug_path(f, "DEQUEUE PATH1", nodeid1, name1, !!wnode1);
1368  debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
1369  }
1370 
1371 #if defined(CHECK_DIR_LOOP)
1372 out_unlock:
1373 #endif
1374  pthread_mutex_unlock(&f->lock);
1375 
1376  return err;
1377 }
1378 
1379 static void free_path_wrlock(struct fuse *f, fuse_ino_t nodeid,
1380  struct node *wnode, char *path)
1381 {
1382  pthread_mutex_lock(&f->lock);
1383  unlock_path(f, nodeid, wnode, NULL);
1384  if (f->lockq)
1385  wake_up_queued(f);
1386  pthread_mutex_unlock(&f->lock);
1387  free(path);
1388 }
1389 
1390 static void free_path(struct fuse *f, fuse_ino_t nodeid, char *path)
1391 {
1392  if (path)
1393  free_path_wrlock(f, nodeid, NULL, path);
1394 }
1395 
1396 static void free_path2(struct fuse *f, fuse_ino_t nodeid1, fuse_ino_t nodeid2,
1397  struct node *wnode1, struct node *wnode2,
1398  char *path1, char *path2)
1399 {
1400  pthread_mutex_lock(&f->lock);
1401  unlock_path(f, nodeid1, wnode1, NULL);
1402  unlock_path(f, nodeid2, wnode2, NULL);
1403  wake_up_queued(f);
1404  pthread_mutex_unlock(&f->lock);
1405  free(path1);
1406  free(path2);
1407 }
1408 
1409 static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup)
1410 {
1411  struct node *node;
1412  if (nodeid == FUSE_ROOT_ID)
1413  return;
1414  pthread_mutex_lock(&f->lock);
1415  node = get_node(f, nodeid);
1416 
1417  /*
1418  * Node may still be locked due to interrupt idiocy in open,
1419  * create and opendir
1420  */
1421  while (node->nlookup == nlookup && node->treelock) {
1422  struct lock_queue_element qe = {
1423  .nodeid1 = nodeid,
1424  };
1425 
1426  debug_path(f, "QUEUE PATH (forget)", nodeid, NULL, false);
1427  queue_path(f, &qe);
1428 
1429  do {
1430  pthread_cond_wait(&qe.cond, &f->lock);
1431  } while (node->nlookup == nlookup && node->treelock);
1432 
1433  dequeue_path(f, &qe);
1434  debug_path(f, "DEQUEUE_PATH (forget)", nodeid, NULL, false);
1435  }
1436 
1437  assert(node->nlookup >= nlookup);
1438  node->nlookup -= nlookup;
1439  if (!node->nlookup) {
1440  unref_node(f, node);
1441  } else if (lru_enabled(f) && node->nlookup == 1) {
1442  set_forget_time(f, node);
1443  }
1444  pthread_mutex_unlock(&f->lock);
1445 }
1446 
1447 static void unlink_node(struct fuse *f, struct node *node)
1448 {
1449  if (f->conf.remember) {
1450  assert(node->nlookup > 1);
1451  node->nlookup--;
1452  }
1453  unhash_name(f, node);
1454 }
1455 
1456 static void remove_node(struct fuse *f, fuse_ino_t dir, const char *name)
1457 {
1458  struct node *node;
1459 
1460  pthread_mutex_lock(&f->lock);
1461  node = lookup_node(f, dir, name);
1462  if (node != NULL)
1463  unlink_node(f, node);
1464  pthread_mutex_unlock(&f->lock);
1465 }
1466 
1467 static int rename_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,
1468  fuse_ino_t newdir, const char *newname, int hide)
1469 {
1470  struct node *node;
1471  struct node *newnode;
1472  int err = 0;
1473 
1474  pthread_mutex_lock(&f->lock);
1475  node = lookup_node(f, olddir, oldname);
1476  newnode = lookup_node(f, newdir, newname);
1477  if (node == NULL)
1478  goto out;
1479 
1480  if (newnode != NULL) {
1481  if (hide) {
1482  fprintf(stderr, "fuse: hidden file got created during hiding\n");
1483  err = -EBUSY;
1484  goto out;
1485  }
1486  unlink_node(f, newnode);
1487  }
1488 
1489  unhash_name(f, node);
1490  if (hash_name(f, node, newdir, newname) == -1) {
1491  err = -ENOMEM;
1492  goto out;
1493  }
1494 
1495  if (hide)
1496  node->is_hidden = 1;
1497 
1498 out:
1499  pthread_mutex_unlock(&f->lock);
1500  return err;
1501 }
1502 
1503 static int exchange_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,
1504  fuse_ino_t newdir, const char *newname)
1505 {
1506  struct node *oldnode;
1507  struct node *newnode;
1508  int err;
1509 
1510  pthread_mutex_lock(&f->lock);
1511  oldnode = lookup_node(f, olddir, oldname);
1512  newnode = lookup_node(f, newdir, newname);
1513 
1514  if (oldnode)
1515  unhash_name(f, oldnode);
1516  if (newnode)
1517  unhash_name(f, newnode);
1518 
1519  err = -ENOMEM;
1520  if (oldnode) {
1521  if (hash_name(f, oldnode, newdir, newname) == -1)
1522  goto out;
1523  }
1524  if (newnode) {
1525  if (hash_name(f, newnode, olddir, oldname) == -1)
1526  goto out;
1527  }
1528  err = 0;
1529 out:
1530  pthread_mutex_unlock(&f->lock);
1531  return err;
1532 }
1533 
1534 static void set_stat(struct fuse *f, fuse_ino_t nodeid, struct stat *stbuf)
1535 {
1536  if (!f->conf.use_ino)
1537  stbuf->st_ino = nodeid;
1538  if (f->conf.set_mode)
1539  stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
1540  (0777 & ~f->conf.umask);
1541  if (f->conf.set_uid)
1542  stbuf->st_uid = f->conf.uid;
1543  if (f->conf.set_gid)
1544  stbuf->st_gid = f->conf.gid;
1545 }
1546 
1547 static struct fuse *req_fuse(fuse_req_t req)
1548 {
1549  return (struct fuse *) fuse_req_userdata(req);
1550 }
1551 
1552 static void fuse_intr_sighandler(int sig)
1553 {
1554  (void) sig;
1555  /* Nothing to do */
1556 }
1557 
1558 struct fuse_intr_data {
1559  pthread_t id;
1560  pthread_cond_t cond;
1561  int finished;
1562 };
1563 
1564 static void fuse_interrupt(fuse_req_t req, void *d_)
1565 {
1566  struct fuse_intr_data *d = d_;
1567  struct fuse *f = req_fuse(req);
1568 
1569  if (d->id == pthread_self())
1570  return;
1571 
1572  pthread_mutex_lock(&f->lock);
1573  while (!d->finished) {
1574  struct timeval now;
1575  struct timespec timeout;
1576 
1577  pthread_kill(d->id, f->conf.intr_signal);
1578  gettimeofday(&now, NULL);
1579  timeout.tv_sec = now.tv_sec + 1;
1580  timeout.tv_nsec = now.tv_usec * 1000;
1581  pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
1582  }
1583  pthread_mutex_unlock(&f->lock);
1584 }
1585 
1586 static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,
1587  struct fuse_intr_data *d)
1588 {
1589  pthread_mutex_lock(&f->lock);
1590  d->finished = 1;
1591  pthread_cond_broadcast(&d->cond);
1592  pthread_mutex_unlock(&f->lock);
1593  fuse_req_interrupt_func(req, NULL, NULL);
1594  pthread_cond_destroy(&d->cond);
1595 }
1596 
1597 static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d)
1598 {
1599  d->id = pthread_self();
1600  pthread_cond_init(&d->cond, NULL);
1601  d->finished = 0;
1602  fuse_req_interrupt_func(req, fuse_interrupt, d);
1603 }
1604 
1605 static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req,
1606  struct fuse_intr_data *d)
1607 {
1608  if (f->conf.intr)
1609  fuse_do_finish_interrupt(f, req, d);
1610 }
1611 
1612 static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,
1613  struct fuse_intr_data *d)
1614 {
1615  if (f->conf.intr)
1616  fuse_do_prepare_interrupt(req, d);
1617 }
1618 
1619 static const char* file_info_string(struct fuse_file_info *fi,
1620  char* buf, size_t len)
1621 {
1622  if(fi == NULL)
1623  return "NULL";
1624  snprintf(buf, len, "%llu", (unsigned long long) fi->fh);
1625  return buf;
1626 }
1627 
1628 int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf,
1629  struct fuse_file_info *fi)
1630 {
1631  fuse_get_context()->private_data = fs->user_data;
1632  if (fs->op.getattr) {
1633  if (fs->debug) {
1634  char buf[10];
1635  fprintf(stderr, "getattr[%s] %s\n",
1636  file_info_string(fi, buf, sizeof(buf)),
1637  path);
1638  }
1639  return fs->op.getattr(path, buf, fi);
1640  } else {
1641  return -ENOSYS;
1642  }
1643 }
1644 
1645 int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
1646  const char *newpath, unsigned int flags)
1647 {
1648  fuse_get_context()->private_data = fs->user_data;
1649  if (fs->op.rename) {
1650  if (fs->debug)
1651  fprintf(stderr, "rename %s %s 0x%x\n", oldpath, newpath,
1652  flags);
1653 
1654  return fs->op.rename(oldpath, newpath, flags);
1655  } else {
1656  return -ENOSYS;
1657  }
1658 }
1659 
1660 int fuse_fs_unlink(struct fuse_fs *fs, const char *path)
1661 {
1662  fuse_get_context()->private_data = fs->user_data;
1663  if (fs->op.unlink) {
1664  if (fs->debug)
1665  fprintf(stderr, "unlink %s\n", path);
1666 
1667  return fs->op.unlink(path);
1668  } else {
1669  return -ENOSYS;
1670  }
1671 }
1672 
1673 int fuse_fs_rmdir(struct fuse_fs *fs, const char *path)
1674 {
1675  fuse_get_context()->private_data = fs->user_data;
1676  if (fs->op.rmdir) {
1677  if (fs->debug)
1678  fprintf(stderr, "rmdir %s\n", path);
1679 
1680  return fs->op.rmdir(path);
1681  } else {
1682  return -ENOSYS;
1683  }
1684 }
1685 
1686 int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path)
1687 {
1688  fuse_get_context()->private_data = fs->user_data;
1689  if (fs->op.symlink) {
1690  if (fs->debug)
1691  fprintf(stderr, "symlink %s %s\n", linkname, path);
1692 
1693  return fs->op.symlink(linkname, path);
1694  } else {
1695  return -ENOSYS;
1696  }
1697 }
1698 
1699 int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath)
1700 {
1701  fuse_get_context()->private_data = fs->user_data;
1702  if (fs->op.link) {
1703  if (fs->debug)
1704  fprintf(stderr, "link %s %s\n", oldpath, newpath);
1705 
1706  return fs->op.link(oldpath, newpath);
1707  } else {
1708  return -ENOSYS;
1709  }
1710 }
1711 
1712 int fuse_fs_release(struct fuse_fs *fs, const char *path,
1713  struct fuse_file_info *fi)
1714 {
1715  fuse_get_context()->private_data = fs->user_data;
1716  if (fs->op.release) {
1717  if (fs->debug)
1718  fprintf(stderr, "release%s[%llu] flags: 0x%x\n",
1719  fi->flush ? "+flush" : "",
1720  (unsigned long long) fi->fh, fi->flags);
1721 
1722  return fs->op.release(path, fi);
1723  } else {
1724  return 0;
1725  }
1726 }
1727 
1728 int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
1729  struct fuse_file_info *fi)
1730 {
1731  fuse_get_context()->private_data = fs->user_data;
1732  if (fs->op.opendir) {
1733  int err;
1734 
1735  if (fs->debug)
1736  fprintf(stderr, "opendir flags: 0x%x %s\n", fi->flags,
1737  path);
1738 
1739  err = fs->op.opendir(path, fi);
1740 
1741  if (fs->debug && !err)
1742  fprintf(stderr, " opendir[%llu] flags: 0x%x %s\n",
1743  (unsigned long long) fi->fh, fi->flags, path);
1744 
1745  return err;
1746  } else {
1747  return 0;
1748  }
1749 }
1750 
1751 int fuse_fs_open(struct fuse_fs *fs, const char *path,
1752  struct fuse_file_info *fi)
1753 {
1754  fuse_get_context()->private_data = fs->user_data;
1755  if (fs->op.open) {
1756  int err;
1757 
1758  if (fs->debug)
1759  fprintf(stderr, "open flags: 0x%x %s\n", fi->flags,
1760  path);
1761 
1762  err = fs->op.open(path, fi);
1763 
1764  if (fs->debug && !err)
1765  fprintf(stderr, " open[%llu] flags: 0x%x %s\n",
1766  (unsigned long long) fi->fh, fi->flags, path);
1767 
1768  return err;
1769  } else {
1770  return 0;
1771  }
1772 }
1773 
1774 static void fuse_free_buf(struct fuse_bufvec *buf)
1775 {
1776  if (buf != NULL) {
1777  size_t i;
1778 
1779  for (i = 0; i < buf->count; i++)
1780  if (!(buf->buf[0].flags & FUSE_BUF_IS_FD))
1781  free(buf->buf[i].mem);
1782  free(buf);
1783  }
1784 }
1785 
1786 int fuse_fs_read_buf(struct fuse_fs *fs, const char *path,
1787  struct fuse_bufvec **bufp, size_t size, off_t off,
1788  struct fuse_file_info *fi)
1789 {
1790  fuse_get_context()->private_data = fs->user_data;
1791  if (fs->op.read || fs->op.read_buf) {
1792  int res;
1793 
1794  if (fs->debug)
1795  fprintf(stderr,
1796  "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1797  (unsigned long long) fi->fh,
1798  size, (unsigned long long) off, fi->flags);
1799 
1800  if (fs->op.read_buf) {
1801  res = fs->op.read_buf(path, bufp, size, off, fi);
1802  } else {
1803  struct fuse_bufvec *buf;
1804  void *mem;
1805 
1806  buf = malloc(sizeof(struct fuse_bufvec));
1807  if (buf == NULL)
1808  return -ENOMEM;
1809 
1810  mem = malloc(size);
1811  if (mem == NULL) {
1812  free(buf);
1813  return -ENOMEM;
1814  }
1815  *buf = FUSE_BUFVEC_INIT(size);
1816  buf->buf[0].mem = mem;
1817  *bufp = buf;
1818 
1819  res = fs->op.read(path, mem, size, off, fi);
1820  if (res >= 0)
1821  buf->buf[0].size = res;
1822  }
1823 
1824  if (fs->debug && res >= 0)
1825  fprintf(stderr, " read[%llu] %zu bytes from %llu\n",
1826  (unsigned long long) fi->fh,
1827  fuse_buf_size(*bufp),
1828  (unsigned long long) off);
1829  if (res >= 0 && fuse_buf_size(*bufp) > size)
1830  fprintf(stderr, "fuse: read too many bytes\n");
1831 
1832  if (res < 0)
1833  return res;
1834 
1835  return 0;
1836  } else {
1837  return -ENOSYS;
1838  }
1839 }
1840 
1841 int fuse_fs_read(struct fuse_fs *fs, const char *path, char *mem, size_t size,
1842  off_t off, struct fuse_file_info *fi)
1843 {
1844  fuse_get_context()->private_data = fs->user_data;
1845  if (fs->op.read || fs->op.read_buf) {
1846  int res;
1847 
1848  if (fs->debug)
1849  fprintf(stderr,
1850  "read[%llu] %zu bytes from %llu flags: 0x%x\n",
1851  (unsigned long long) fi->fh,
1852  size, (unsigned long long) off, fi->flags);
1853 
1854  if (fs->op.read_buf) {
1855  struct fuse_bufvec *buf = NULL;
1856 
1857  res = fs->op.read_buf(path, &buf, size, off, fi);
1858  if (res == 0) {
1859  struct fuse_bufvec dst = FUSE_BUFVEC_INIT(size);
1860 
1861  dst.buf[0].mem = mem;
1862  res = fuse_buf_copy(&dst, buf, 0);
1863  }
1864  fuse_free_buf(buf);
1865  } else {
1866  res = fs->op.read(path, mem, size, off, fi);
1867  }
1868 
1869  if (fs->debug && res >= 0)
1870  fprintf(stderr, " read[%llu] %u bytes from %llu\n",
1871  (unsigned long long) fi->fh,
1872  res,
1873  (unsigned long long) off);
1874  if (res >= 0 && res > (int) size)
1875  fprintf(stderr, "fuse: read too many bytes\n");
1876 
1877  return res;
1878  } else {
1879  return -ENOSYS;
1880  }
1881 }
1882 
1883 int fuse_fs_write_buf(struct fuse_fs *fs, const char *path,
1884  struct fuse_bufvec *buf, off_t off,
1885  struct fuse_file_info *fi)
1886 {
1887  fuse_get_context()->private_data = fs->user_data;
1888  if (fs->op.write_buf || fs->op.write) {
1889  int res;
1890  size_t size = fuse_buf_size(buf);
1891 
1892  assert(buf->idx == 0 && buf->off == 0);
1893  if (fs->debug)
1894  fprintf(stderr,
1895  "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
1896  fi->writepage ? "page" : "",
1897  (unsigned long long) fi->fh,
1898  size,
1899  (unsigned long long) off,
1900  fi->flags);
1901 
1902  if (fs->op.write_buf) {
1903  res = fs->op.write_buf(path, buf, off, fi);
1904  } else {
1905  void *mem = NULL;
1906  struct fuse_buf *flatbuf;
1907  struct fuse_bufvec tmp = FUSE_BUFVEC_INIT(size);
1908 
1909  if (buf->count == 1 &&
1910  !(buf->buf[0].flags & FUSE_BUF_IS_FD)) {
1911  flatbuf = &buf->buf[0];
1912  } else {
1913  res = -ENOMEM;
1914  mem = malloc(size);
1915  if (mem == NULL)
1916  goto out;
1917 
1918  tmp.buf[0].mem = mem;
1919  res = fuse_buf_copy(&tmp, buf, 0);
1920  if (res <= 0)
1921  goto out_free;
1922 
1923  tmp.buf[0].size = res;
1924  flatbuf = &tmp.buf[0];
1925  }
1926 
1927  res = fs->op.write(path, flatbuf->mem, flatbuf->size,
1928  off, fi);
1929 out_free:
1930  free(mem);
1931  }
1932 out:
1933  if (fs->debug && res >= 0)
1934  fprintf(stderr, " write%s[%llu] %u bytes to %llu\n",
1935  fi->writepage ? "page" : "",
1936  (unsigned long long) fi->fh, res,
1937  (unsigned long long) off);
1938  if (res > (int) size)
1939  fprintf(stderr, "fuse: wrote too many bytes\n");
1940 
1941  return res;
1942  } else {
1943  return -ENOSYS;
1944  }
1945 }
1946 
1947 int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *mem,
1948  size_t size, off_t off, struct fuse_file_info *fi)
1949 {
1950  struct fuse_bufvec bufv = FUSE_BUFVEC_INIT(size);
1951 
1952  bufv.buf[0].mem = (void *) mem;
1953 
1954  return fuse_fs_write_buf(fs, path, &bufv, off, fi);
1955 }
1956 
1957 int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
1958  struct fuse_file_info *fi)
1959 {
1960  fuse_get_context()->private_data = fs->user_data;
1961  if (fs->op.fsync) {
1962  if (fs->debug)
1963  fprintf(stderr, "fsync[%llu] datasync: %i\n",
1964  (unsigned long long) fi->fh, datasync);
1965 
1966  return fs->op.fsync(path, datasync, fi);
1967  } else {
1968  return -ENOSYS;
1969  }
1970 }
1971 
1972 int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
1973  struct fuse_file_info *fi)
1974 {
1975  fuse_get_context()->private_data = fs->user_data;
1976  if (fs->op.fsyncdir) {
1977  if (fs->debug)
1978  fprintf(stderr, "fsyncdir[%llu] datasync: %i\n",
1979  (unsigned long long) fi->fh, datasync);
1980 
1981  return fs->op.fsyncdir(path, datasync, fi);
1982  } else {
1983  return -ENOSYS;
1984  }
1985 }
1986 
1987 int fuse_fs_flush(struct fuse_fs *fs, const char *path,
1988  struct fuse_file_info *fi)
1989 {
1990  fuse_get_context()->private_data = fs->user_data;
1991  if (fs->op.flush) {
1992  if (fs->debug)
1993  fprintf(stderr, "flush[%llu]\n",
1994  (unsigned long long) fi->fh);
1995 
1996  return fs->op.flush(path, fi);
1997  } else {
1998  return -ENOSYS;
1999  }
2000 }
2001 
2002 int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf)
2003 {
2004  fuse_get_context()->private_data = fs->user_data;
2005  if (fs->op.statfs) {
2006  if (fs->debug)
2007  fprintf(stderr, "statfs %s\n", path);
2008 
2009  return fs->op.statfs(path, buf);
2010  } else {
2011  buf->f_namemax = 255;
2012  buf->f_bsize = 512;
2013  return 0;
2014  }
2015 }
2016 
2017 int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
2018  struct fuse_file_info *fi)
2019 {
2020  fuse_get_context()->private_data = fs->user_data;
2021  if (fs->op.releasedir) {
2022  if (fs->debug)
2023  fprintf(stderr, "releasedir[%llu] flags: 0x%x\n",
2024  (unsigned long long) fi->fh, fi->flags);
2025 
2026  return fs->op.releasedir(path, fi);
2027  } else {
2028  return 0;
2029  }
2030 }
2031 
2032 int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
2033  fuse_fill_dir_t filler, off_t off,
2034  struct fuse_file_info *fi,
2035  enum fuse_readdir_flags flags)
2036 {
2037  fuse_get_context()->private_data = fs->user_data;
2038  if (fs->op.readdir) {
2039  if (fs->debug) {
2040  fprintf(stderr, "readdir%s[%llu] from %llu\n",
2041  (flags & FUSE_READDIR_PLUS) ? "plus" : "",
2042  (unsigned long long) fi->fh,
2043  (unsigned long long) off);
2044  }
2045 
2046  return fs->op.readdir(path, buf, filler, off, fi, flags);
2047  } else {
2048  return -ENOSYS;
2049  }
2050 }
2051 
2052 int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
2053  struct fuse_file_info *fi)
2054 {
2055  fuse_get_context()->private_data = fs->user_data;
2056  if (fs->op.create) {
2057  int err;
2058 
2059  if (fs->debug)
2060  fprintf(stderr,
2061  "create flags: 0x%x %s 0%o umask=0%03o\n",
2062  fi->flags, path, mode,
2063  fuse_get_context()->umask);
2064 
2065  err = fs->op.create(path, mode, fi);
2066 
2067  if (fs->debug && !err)
2068  fprintf(stderr, " create[%llu] flags: 0x%x %s\n",
2069  (unsigned long long) fi->fh, fi->flags, path);
2070 
2071  return err;
2072  } else {
2073  return -ENOSYS;
2074  }
2075 }
2076 
2077 int fuse_fs_lock(struct fuse_fs *fs, const char *path,
2078  struct fuse_file_info *fi, int cmd, struct flock *lock)
2079 {
2080  fuse_get_context()->private_data = fs->user_data;
2081  if (fs->op.lock) {
2082  if (fs->debug)
2083  fprintf(stderr, "lock[%llu] %s %s start: %llu len: %llu pid: %llu\n",
2084  (unsigned long long) fi->fh,
2085  (cmd == F_GETLK ? "F_GETLK" :
2086  (cmd == F_SETLK ? "F_SETLK" :
2087  (cmd == F_SETLKW ? "F_SETLKW" : "???"))),
2088  (lock->l_type == F_RDLCK ? "F_RDLCK" :
2089  (lock->l_type == F_WRLCK ? "F_WRLCK" :
2090  (lock->l_type == F_UNLCK ? "F_UNLCK" :
2091  "???"))),
2092  (unsigned long long) lock->l_start,
2093  (unsigned long long) lock->l_len,
2094  (unsigned long long) lock->l_pid);
2095 
2096  return fs->op.lock(path, fi, cmd, lock);
2097  } else {
2098  return -ENOSYS;
2099  }
2100 }
2101 
2102 int fuse_fs_flock(struct fuse_fs *fs, const char *path,
2103  struct fuse_file_info *fi, int op)
2104 {
2105  fuse_get_context()->private_data = fs->user_data;
2106  if (fs->op.flock) {
2107  if (fs->debug) {
2108  int xop = op & ~LOCK_NB;
2109 
2110  fprintf(stderr, "lock[%llu] %s%s\n",
2111  (unsigned long long) fi->fh,
2112  xop == LOCK_SH ? "LOCK_SH" :
2113  (xop == LOCK_EX ? "LOCK_EX" :
2114  (xop == LOCK_UN ? "LOCK_UN" : "???")),
2115  (op & LOCK_NB) ? "|LOCK_NB" : "");
2116  }
2117  return fs->op.flock(path, fi, op);
2118  } else {
2119  return -ENOSYS;
2120  }
2121 }
2122 
2123 int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid,
2124  gid_t gid, struct fuse_file_info *fi)
2125 {
2126  fuse_get_context()->private_data = fs->user_data;
2127  if (fs->op.chown) {
2128  if (fs->debug) {
2129  char buf[10];
2130  fprintf(stderr, "chown[%s] %s %lu %lu\n",
2131  file_info_string(fi, buf, sizeof(buf)),
2132  path, (unsigned long) uid, (unsigned long) gid);
2133  }
2134  return fs->op.chown(path, uid, gid, fi);
2135  } else {
2136  return -ENOSYS;
2137  }
2138 }
2139 
2140 int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size,
2141  struct fuse_file_info *fi)
2142 {
2143  fuse_get_context()->private_data = fs->user_data;
2144  if (fs->op.truncate) {
2145  if (fs->debug) {
2146  char buf[10];
2147  fprintf(stderr, "truncate[%s] %llu\n",
2148  file_info_string(fi, buf, sizeof(buf)),
2149  (unsigned long long) size);
2150  }
2151  return fs->op.truncate(path, size, fi);
2152  } else {
2153  return -ENOSYS;
2154  }
2155 }
2156 
2157 int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
2158  const struct timespec tv[2], struct fuse_file_info *fi)
2159 {
2160  fuse_get_context()->private_data = fs->user_data;
2161  if (fs->op.utimens) {
2162  if (fs->debug) {
2163  char buf[10];
2164  fprintf(stderr, "utimens[%s] %s %li.%09lu %li.%09lu\n",
2165  file_info_string(fi, buf, sizeof(buf)),
2166  path, tv[0].tv_sec, tv[0].tv_nsec,
2167  tv[1].tv_sec, tv[1].tv_nsec);
2168  }
2169  return fs->op.utimens(path, tv, fi);
2170  } else {
2171  return -ENOSYS;
2172  }
2173 }
2174 
2175 int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask)
2176 {
2177  fuse_get_context()->private_data = fs->user_data;
2178  if (fs->op.access) {
2179  if (fs->debug)
2180  fprintf(stderr, "access %s 0%o\n", path, mask);
2181 
2182  return fs->op.access(path, mask);
2183  } else {
2184  return -ENOSYS;
2185  }
2186 }
2187 
2188 int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
2189  size_t len)
2190 {
2191  fuse_get_context()->private_data = fs->user_data;
2192  if (fs->op.readlink) {
2193  if (fs->debug)
2194  fprintf(stderr, "readlink %s %lu\n", path,
2195  (unsigned long) len);
2196 
2197  return fs->op.readlink(path, buf, len);
2198  } else {
2199  return -ENOSYS;
2200  }
2201 }
2202 
2203 int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
2204  dev_t rdev)
2205 {
2206  fuse_get_context()->private_data = fs->user_data;
2207  if (fs->op.mknod) {
2208  if (fs->debug)
2209  fprintf(stderr, "mknod %s 0%o 0x%llx umask=0%03o\n",
2210  path, mode, (unsigned long long) rdev,
2211  fuse_get_context()->umask);
2212 
2213  return fs->op.mknod(path, mode, rdev);
2214  } else {
2215  return -ENOSYS;
2216  }
2217 }
2218 
2219 int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode)
2220 {
2221  fuse_get_context()->private_data = fs->user_data;
2222  if (fs->op.mkdir) {
2223  if (fs->debug)
2224  fprintf(stderr, "mkdir %s 0%o umask=0%03o\n",
2225  path, mode, fuse_get_context()->umask);
2226 
2227  return fs->op.mkdir(path, mode);
2228  } else {
2229  return -ENOSYS;
2230  }
2231 }
2232 
2233 int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
2234  const char *value, size_t size, int flags)
2235 {
2236  fuse_get_context()->private_data = fs->user_data;
2237  if (fs->op.setxattr) {
2238  if (fs->debug)
2239  fprintf(stderr, "setxattr %s %s %lu 0x%x\n",
2240  path, name, (unsigned long) size, flags);
2241 
2242  return fs->op.setxattr(path, name, value, size, flags);
2243  } else {
2244  return -ENOSYS;
2245  }
2246 }
2247 
2248 int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
2249  char *value, size_t size)
2250 {
2251  fuse_get_context()->private_data = fs->user_data;
2252  if (fs->op.getxattr) {
2253  if (fs->debug)
2254  fprintf(stderr, "getxattr %s %s %lu\n",
2255  path, name, (unsigned long) size);
2256 
2257  return fs->op.getxattr(path, name, value, size);
2258  } else {
2259  return -ENOSYS;
2260  }
2261 }
2262 
2263 int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
2264  size_t size)
2265 {
2266  fuse_get_context()->private_data = fs->user_data;
2267  if (fs->op.listxattr) {
2268  if (fs->debug)
2269  fprintf(stderr, "listxattr %s %lu\n",
2270  path, (unsigned long) size);
2271 
2272  return fs->op.listxattr(path, list, size);
2273  } else {
2274  return -ENOSYS;
2275  }
2276 }
2277 
2278 int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
2279  uint64_t *idx)
2280 {
2281  fuse_get_context()->private_data = fs->user_data;
2282  if (fs->op.bmap) {
2283  if (fs->debug)
2284  fprintf(stderr, "bmap %s blocksize: %lu index: %llu\n",
2285  path, (unsigned long) blocksize,
2286  (unsigned long long) *idx);
2287 
2288  return fs->op.bmap(path, blocksize, idx);
2289  } else {
2290  return -ENOSYS;
2291  }
2292 }
2293 
2294 int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name)
2295 {
2296  fuse_get_context()->private_data = fs->user_data;
2297  if (fs->op.removexattr) {
2298  if (fs->debug)
2299  fprintf(stderr, "removexattr %s %s\n", path, name);
2300 
2301  return fs->op.removexattr(path, name);
2302  } else {
2303  return -ENOSYS;
2304  }
2305 }
2306 
2307 int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg,
2308  struct fuse_file_info *fi, unsigned int flags, void *data)
2309 {
2310  fuse_get_context()->private_data = fs->user_data;
2311  if (fs->op.ioctl) {
2312  if (fs->debug)
2313  fprintf(stderr, "ioctl[%llu] 0x%x flags: 0x%x\n",
2314  (unsigned long long) fi->fh, cmd, flags);
2315 
2316  return fs->op.ioctl(path, cmd, arg, fi, flags, data);
2317  } else
2318  return -ENOSYS;
2319 }
2320 
2321 int fuse_fs_poll(struct fuse_fs *fs, const char *path,
2322  struct fuse_file_info *fi, struct fuse_pollhandle *ph,
2323  unsigned *reventsp)
2324 {
2325  fuse_get_context()->private_data = fs->user_data;
2326  if (fs->op.poll) {
2327  int res;
2328 
2329  if (fs->debug)
2330  fprintf(stderr, "poll[%llu] ph: %p, events 0x%x\n",
2331  (unsigned long long) fi->fh, ph,
2332  fi->poll_events);
2333 
2334  res = fs->op.poll(path, fi, ph, reventsp);
2335 
2336  if (fs->debug && !res)
2337  fprintf(stderr, " poll[%llu] revents: 0x%x\n",
2338  (unsigned long long) fi->fh, *reventsp);
2339 
2340  return res;
2341  } else
2342  return -ENOSYS;
2343 }
2344 
2345 int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,
2346  off_t offset, off_t length, struct fuse_file_info *fi)
2347 {
2348  fuse_get_context()->private_data = fs->user_data;
2349  if (fs->op.fallocate) {
2350  if (fs->debug)
2351  fprintf(stderr, "fallocate %s mode %x, offset: %llu, length: %llu\n",
2352  path,
2353  mode,
2354  (unsigned long long) offset,
2355  (unsigned long long) length);
2356 
2357  return fs->op.fallocate(path, mode, offset, length, fi);
2358  } else
2359  return -ENOSYS;
2360 }
2361 
2362 ssize_t fuse_fs_copy_file_range(struct fuse_fs *fs, const char *path_in,
2363  struct fuse_file_info *fi_in, off_t off_in,
2364  const char *path_out,
2365  struct fuse_file_info *fi_out, off_t off_out,
2366  size_t len, int flags)
2367 {
2368  fuse_get_context()->private_data = fs->user_data;
2369  if (fs->op.copy_file_range) {
2370  if (fs->debug)
2371  fprintf(stderr, "copy_file_range from %s:%llu to "
2372  "%s:%llu, length: %llu\n",
2373  path_in,
2374  (unsigned long long) off_in,
2375  path_out,
2376  (unsigned long long) off_out,
2377  (unsigned long long) len);
2378 
2379  return fs->op.copy_file_range(path_in, fi_in, off_in, path_out,
2380  fi_out, off_out, len, flags);
2381  } else
2382  return -ENOSYS;
2383 }
2384 
2385 static int is_open(struct fuse *f, fuse_ino_t dir, const char *name)
2386 {
2387  struct node *node;
2388  int isopen = 0;
2389  pthread_mutex_lock(&f->lock);
2390  node = lookup_node(f, dir, name);
2391  if (node && node->open_count > 0)
2392  isopen = 1;
2393  pthread_mutex_unlock(&f->lock);
2394  return isopen;
2395 }
2396 
2397 static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,
2398  char *newname, size_t bufsize)
2399 {
2400  struct stat buf;
2401  struct node *node;
2402  struct node *newnode;
2403  char *newpath;
2404  int res;
2405  int failctr = 10;
2406 
2407  do {
2408  pthread_mutex_lock(&f->lock);
2409  node = lookup_node(f, dir, oldname);
2410  if (node == NULL) {
2411  pthread_mutex_unlock(&f->lock);
2412  return NULL;
2413  }
2414  do {
2415  f->hidectr ++;
2416  snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
2417  (unsigned int) node->nodeid, f->hidectr);
2418  newnode = lookup_node(f, dir, newname);
2419  } while(newnode);
2420 
2421  res = try_get_path(f, dir, newname, &newpath, NULL, false);
2422  pthread_mutex_unlock(&f->lock);
2423  if (res)
2424  break;
2425 
2426  memset(&buf, 0, sizeof(buf));
2427  res = fuse_fs_getattr(f->fs, newpath, &buf, NULL);
2428  if (res == -ENOENT)
2429  break;
2430  free(newpath);
2431  newpath = NULL;
2432  } while(res == 0 && --failctr);
2433 
2434  return newpath;
2435 }
2436 
2437 static int hide_node(struct fuse *f, const char *oldpath,
2438  fuse_ino_t dir, const char *oldname)
2439 {
2440  char newname[64];
2441  char *newpath;
2442  int err = -EBUSY;
2443 
2444  newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
2445  if (newpath) {
2446  err = fuse_fs_rename(f->fs, oldpath, newpath, 0);
2447  if (!err)
2448  err = rename_node(f, dir, oldname, dir, newname, 1);
2449  free(newpath);
2450  }
2451  return err;
2452 }
2453 
2454 static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
2455 {
2456  return stbuf->st_mtime == ts->tv_sec &&
2457  ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
2458 }
2459 
2460 #ifndef CLOCK_MONOTONIC
2461 #define CLOCK_MONOTONIC CLOCK_REALTIME
2462 #endif
2463 
2464 static void curr_time(struct timespec *now)
2465 {
2466  static clockid_t clockid = CLOCK_MONOTONIC;
2467  int res = clock_gettime(clockid, now);
2468  if (res == -1 && errno == EINVAL) {
2469  clockid = CLOCK_REALTIME;
2470  res = clock_gettime(clockid, now);
2471  }
2472  if (res == -1) {
2473  perror("fuse: clock_gettime");
2474  abort();
2475  }
2476 }
2477 
2478 static void update_stat(struct node *node, const struct stat *stbuf)
2479 {
2480  if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
2481  stbuf->st_size != node->size))
2482  node->cache_valid = 0;
2483  node->mtime.tv_sec = stbuf->st_mtime;
2484  node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
2485  node->size = stbuf->st_size;
2486  curr_time(&node->stat_updated);
2487 }
2488 
2489 static int do_lookup(struct fuse *f, fuse_ino_t nodeid, const char *name,
2490  struct fuse_entry_param *e)
2491 {
2492  struct node *node;
2493 
2494  node = find_node(f, nodeid, name);
2495  if (node == NULL)
2496  return -ENOMEM;
2497 
2498  e->ino = node->nodeid;
2499  e->generation = node->generation;
2500  e->entry_timeout = f->conf.entry_timeout;
2501  e->attr_timeout = f->conf.attr_timeout;
2502  if (f->conf.auto_cache) {
2503  pthread_mutex_lock(&f->lock);
2504  update_stat(node, &e->attr);
2505  pthread_mutex_unlock(&f->lock);
2506  }
2507  set_stat(f, e->ino, &e->attr);
2508  return 0;
2509 }
2510 
2511 static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
2512  const char *name, const char *path,
2513  struct fuse_entry_param *e, struct fuse_file_info *fi)
2514 {
2515  int res;
2516 
2517  memset(e, 0, sizeof(struct fuse_entry_param));
2518  res = fuse_fs_getattr(f->fs, path, &e->attr, fi);
2519  if (res == 0) {
2520  res = do_lookup(f, nodeid, name, e);
2521  if (res == 0 && f->conf.debug) {
2522  fprintf(stderr, " NODEID: %llu\n",
2523  (unsigned long long) e->ino);
2524  }
2525  }
2526  return res;
2527 }
2528 
2529 static struct fuse_context_i *fuse_get_context_internal(void)
2530 {
2531  return (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
2532 }
2533 
2534 static struct fuse_context_i *fuse_create_context(struct fuse *f)
2535 {
2536  struct fuse_context_i *c = fuse_get_context_internal();
2537  if (c == NULL) {
2538  c = (struct fuse_context_i *)
2539  calloc(1, sizeof(struct fuse_context_i));
2540  if (c == NULL) {
2541  /* This is hard to deal with properly, so just
2542  abort. If memory is so low that the
2543  context cannot be allocated, there's not
2544  much hope for the filesystem anyway */
2545  fprintf(stderr, "fuse: failed to allocate thread specific data\n");
2546  abort();
2547  }
2548  pthread_setspecific(fuse_context_key, c);
2549  } else {
2550  memset(c, 0, sizeof(*c));
2551  }
2552  c->ctx.fuse = f;
2553 
2554  return c;
2555 }
2556 
2557 static void fuse_freecontext(void *data)
2558 {
2559  free(data);
2560 }
2561 
2562 static int fuse_create_context_key(void)
2563 {
2564  int err = 0;
2565  pthread_mutex_lock(&fuse_context_lock);
2566  if (!fuse_context_ref) {
2567  err = pthread_key_create(&fuse_context_key, fuse_freecontext);
2568  if (err) {
2569  fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
2570  strerror(err));
2571  pthread_mutex_unlock(&fuse_context_lock);
2572  return -1;
2573  }
2574  }
2575  fuse_context_ref++;
2576  pthread_mutex_unlock(&fuse_context_lock);
2577  return 0;
2578 }
2579 
2580 static void fuse_delete_context_key(void)
2581 {
2582  pthread_mutex_lock(&fuse_context_lock);
2583  fuse_context_ref--;
2584  if (!fuse_context_ref) {
2585  free(pthread_getspecific(fuse_context_key));
2586  pthread_key_delete(fuse_context_key);
2587  }
2588  pthread_mutex_unlock(&fuse_context_lock);
2589 }
2590 
2591 static struct fuse *req_fuse_prepare(fuse_req_t req)
2592 {
2593  struct fuse_context_i *c = fuse_create_context(req_fuse(req));
2594  const struct fuse_ctx *ctx = fuse_req_ctx(req);
2595  c->req = req;
2596  c->ctx.uid = ctx->uid;
2597  c->ctx.gid = ctx->gid;
2598  c->ctx.pid = ctx->pid;
2599  c->ctx.umask = ctx->umask;
2600  return c->ctx.fuse;
2601 }
2602 
2603 static inline void reply_err(fuse_req_t req, int err)
2604 {
2605  /* fuse_reply_err() uses non-negated errno values */
2606  fuse_reply_err(req, -err);
2607 }
2608 
2609 static void reply_entry(fuse_req_t req, const struct fuse_entry_param *e,
2610  int err)
2611 {
2612  if (!err) {
2613  struct fuse *f = req_fuse(req);
2614  if (fuse_reply_entry(req, e) == -ENOENT) {
2615  /* Skip forget for negative result */
2616  if (e->ino != 0)
2617  forget_node(f, e->ino, 1);
2618  }
2619  } else
2620  reply_err(req, err);
2621 }
2622 
2623 void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn,
2624  struct fuse_config *cfg)
2625 {
2626  fuse_get_context()->private_data = fs->user_data;
2627  if (!fs->op.write_buf)
2628  conn->want &= ~FUSE_CAP_SPLICE_READ;
2629  if (!fs->op.lock)
2630  conn->want &= ~FUSE_CAP_POSIX_LOCKS;
2631  if (!fs->op.flock)
2632  conn->want &= ~FUSE_CAP_FLOCK_LOCKS;
2633  if (fs->op.init)
2634  fs->user_data = fs->op.init(conn, cfg);
2635 }
2636 
2637 static void fuse_lib_init(void *data, struct fuse_conn_info *conn)
2638 {
2639  struct fuse *f = (struct fuse *) data;
2640 
2641  fuse_create_context(f);
2642  if(conn->capable & FUSE_CAP_EXPORT_SUPPORT)
2643  conn->want |= FUSE_CAP_EXPORT_SUPPORT;
2644  fuse_fs_init(f->fs, conn, &f->conf);
2645 }
2646 
2647 void fuse_fs_destroy(struct fuse_fs *fs)
2648 {
2649  fuse_get_context()->private_data = fs->user_data;
2650  if (fs->op.destroy)
2651  fs->op.destroy(fs->user_data);
2652  if (fs->m)
2653  fuse_put_module(fs->m);
2654  free(fs);
2655 }
2656 
2657 static void fuse_lib_destroy(void *data)
2658 {
2659  struct fuse *f = (struct fuse *) data;
2660 
2661  fuse_create_context(f);
2662  fuse_fs_destroy(f->fs);
2663  f->fs = NULL;
2664 }
2665 
2666 static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent,
2667  const char *name)
2668 {
2669  struct fuse *f = req_fuse_prepare(req);
2670  struct fuse_entry_param e;
2671  char *path;
2672  int err;
2673  struct node *dot = NULL;
2674 
2675  if (name[0] == '.') {
2676  int len = strlen(name);
2677 
2678  if (len == 1 || (name[1] == '.' && len == 2)) {
2679  pthread_mutex_lock(&f->lock);
2680  if (len == 1) {
2681  if (f->conf.debug)
2682  fprintf(stderr, "LOOKUP-DOT\n");
2683  dot = get_node_nocheck(f, parent);
2684  if (dot == NULL) {
2685  pthread_mutex_unlock(&f->lock);
2686  reply_entry(req, &e, -ESTALE);
2687  return;
2688  }
2689  dot->refctr++;
2690  } else {
2691  if (f->conf.debug)
2692  fprintf(stderr, "LOOKUP-DOTDOT\n");
2693  parent = get_node(f, parent)->parent->nodeid;
2694  }
2695  pthread_mutex_unlock(&f->lock);
2696  name = NULL;
2697  }
2698  }
2699 
2700  err = get_path_name(f, parent, name, &path);
2701  if (!err) {
2702  struct fuse_intr_data d;
2703  if (f->conf.debug)
2704  fprintf(stderr, "LOOKUP %s\n", path);
2705  fuse_prepare_interrupt(f, req, &d);
2706  err = lookup_path(f, parent, name, path, &e, NULL);
2707  if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
2708  e.ino = 0;
2709  e.entry_timeout = f->conf.negative_timeout;
2710  err = 0;
2711  }
2712  fuse_finish_interrupt(f, req, &d);
2713  free_path(f, parent, path);
2714  }
2715  if (dot) {
2716  pthread_mutex_lock(&f->lock);
2717  unref_node(f, dot);
2718  pthread_mutex_unlock(&f->lock);
2719  }
2720  reply_entry(req, &e, err);
2721 }
2722 
2723 static void do_forget(struct fuse *f, fuse_ino_t ino, uint64_t nlookup)
2724 {
2725  if (f->conf.debug)
2726  fprintf(stderr, "FORGET %llu/%llu\n", (unsigned long long)ino,
2727  (unsigned long long) nlookup);
2728  forget_node(f, ino, nlookup);
2729 }
2730 
2731 static void fuse_lib_forget(fuse_req_t req, fuse_ino_t ino, uint64_t nlookup)
2732 {
2733  do_forget(req_fuse(req), ino, nlookup);
2734  fuse_reply_none(req);
2735 }
2736 
2737 static void fuse_lib_forget_multi(fuse_req_t req, size_t count,
2738  struct fuse_forget_data *forgets)
2739 {
2740  struct fuse *f = req_fuse(req);
2741  size_t i;
2742 
2743  for (i = 0; i < count; i++)
2744  do_forget(f, forgets[i].ino, forgets[i].nlookup);
2745 
2746  fuse_reply_none(req);
2747 }
2748 
2749 
2750 static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
2751  struct fuse_file_info *fi)
2752 {
2753  struct fuse *f = req_fuse_prepare(req);
2754  struct stat buf;
2755  char *path;
2756  int err;
2757 
2758  memset(&buf, 0, sizeof(buf));
2759 
2760  if (fi != NULL)
2761  err = get_path_nullok(f, ino, &path);
2762  else
2763  err = get_path(f, ino, &path);
2764  if (!err) {
2765  struct fuse_intr_data d;
2766  fuse_prepare_interrupt(f, req, &d);
2767  err = fuse_fs_getattr(f->fs, path, &buf, fi);
2768  fuse_finish_interrupt(f, req, &d);
2769  free_path(f, ino, path);
2770  }
2771  if (!err) {
2772  struct node *node;
2773 
2774  pthread_mutex_lock(&f->lock);
2775  node = get_node(f, ino);
2776  if (node->is_hidden && buf.st_nlink > 0)
2777  buf.st_nlink--;
2778  if (f->conf.auto_cache)
2779  update_stat(node, &buf);
2780  pthread_mutex_unlock(&f->lock);
2781  set_stat(f, ino, &buf);
2782  fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2783  } else
2784  reply_err(req, err);
2785 }
2786 
2787 int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode,
2788  struct fuse_file_info *fi)
2789 {
2790  fuse_get_context()->private_data = fs->user_data;
2791  if (fs->op.chmod) {
2792  if (fs->debug) {
2793  char buf[10];
2794  fprintf(stderr, "chmod[%s] %s %llo\n",
2795  file_info_string(fi, buf, sizeof(buf)),
2796  path, (unsigned long long) mode);
2797  }
2798  return fs->op.chmod(path, mode, fi);
2799  }
2800  else
2801  return -ENOSYS;
2802 }
2803 
2804 static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
2805  int valid, struct fuse_file_info *fi)
2806 {
2807  struct fuse *f = req_fuse_prepare(req);
2808  struct stat buf;
2809  char *path;
2810  int err;
2811 
2812  memset(&buf, 0, sizeof(buf));
2813  if (fi != NULL)
2814  err = get_path_nullok(f, ino, &path);
2815  else
2816  err = get_path(f, ino, &path);
2817  if (!err) {
2818  struct fuse_intr_data d;
2819  fuse_prepare_interrupt(f, req, &d);
2820  err = 0;
2821  if (!err && (valid & FUSE_SET_ATTR_MODE))
2822  err = fuse_fs_chmod(f->fs, path, attr->st_mode, fi);
2823  if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
2824  uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
2825  attr->st_uid : (uid_t) -1;
2826  gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
2827  attr->st_gid : (gid_t) -1;
2828  err = fuse_fs_chown(f->fs, path, uid, gid, fi);
2829  }
2830  if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
2831  err = fuse_fs_truncate(f->fs, path,
2832  attr->st_size, fi);
2833  }
2834 #ifdef HAVE_UTIMENSAT
2835  if (!err &&
2836  (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
2837  struct timespec tv[2];
2838 
2839  tv[0].tv_sec = 0;
2840  tv[1].tv_sec = 0;
2841  tv[0].tv_nsec = UTIME_OMIT;
2842  tv[1].tv_nsec = UTIME_OMIT;
2843 
2844  if (valid & FUSE_SET_ATTR_ATIME_NOW)
2845  tv[0].tv_nsec = UTIME_NOW;
2846  else if (valid & FUSE_SET_ATTR_ATIME)
2847  tv[0] = attr->st_atim;
2848 
2849  if (valid & FUSE_SET_ATTR_MTIME_NOW)
2850  tv[1].tv_nsec = UTIME_NOW;
2851  else if (valid & FUSE_SET_ATTR_MTIME)
2852  tv[1] = attr->st_mtim;
2853 
2854  err = fuse_fs_utimens(f->fs, path, tv, fi);
2855  } else
2856 #endif
2857  if (!err &&
2858  (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
2859  (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
2860  struct timespec tv[2];
2861  tv[0].tv_sec = attr->st_atime;
2862  tv[0].tv_nsec = ST_ATIM_NSEC(attr);
2863  tv[1].tv_sec = attr->st_mtime;
2864  tv[1].tv_nsec = ST_MTIM_NSEC(attr);
2865  err = fuse_fs_utimens(f->fs, path, tv, fi);
2866  }
2867  if (!err) {
2868  err = fuse_fs_getattr(f->fs, path, &buf, fi);
2869  }
2870  fuse_finish_interrupt(f, req, &d);
2871  free_path(f, ino, path);
2872  }
2873  if (!err) {
2874  if (f->conf.auto_cache) {
2875  pthread_mutex_lock(&f->lock);
2876  update_stat(get_node(f, ino), &buf);
2877  pthread_mutex_unlock(&f->lock);
2878  }
2879  set_stat(f, ino, &buf);
2880  fuse_reply_attr(req, &buf, f->conf.attr_timeout);
2881  } else
2882  reply_err(req, err);
2883 }
2884 
2885 static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask)
2886 {
2887  struct fuse *f = req_fuse_prepare(req);
2888  char *path;
2889  int err;
2890 
2891  err = get_path(f, ino, &path);
2892  if (!err) {
2893  struct fuse_intr_data d;
2894 
2895  fuse_prepare_interrupt(f, req, &d);
2896  err = fuse_fs_access(f->fs, path, mask);
2897  fuse_finish_interrupt(f, req, &d);
2898  free_path(f, ino, path);
2899  }
2900  reply_err(req, err);
2901 }
2902 
2903 static void fuse_lib_readlink(fuse_req_t req, fuse_ino_t ino)
2904 {
2905  struct fuse *f = req_fuse_prepare(req);
2906  char linkname[PATH_MAX + 1];
2907  char *path;
2908  int err;
2909 
2910  err = get_path(f, ino, &path);
2911  if (!err) {
2912  struct fuse_intr_data d;
2913  fuse_prepare_interrupt(f, req, &d);
2914  err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
2915  fuse_finish_interrupt(f, req, &d);
2916  free_path(f, ino, path);
2917  }
2918  if (!err) {
2919  linkname[PATH_MAX] = '\0';
2920  fuse_reply_readlink(req, linkname);
2921  } else
2922  reply_err(req, err);
2923 }
2924 
2925 static void fuse_lib_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
2926  mode_t mode, dev_t rdev)
2927 {
2928  struct fuse *f = req_fuse_prepare(req);
2929  struct fuse_entry_param e;
2930  char *path;
2931  int err;
2932 
2933  err = get_path_name(f, parent, name, &path);
2934  if (!err) {
2935  struct fuse_intr_data d;
2936 
2937  fuse_prepare_interrupt(f, req, &d);
2938  err = -ENOSYS;
2939  if (S_ISREG(mode)) {
2940  struct fuse_file_info fi;
2941 
2942  memset(&fi, 0, sizeof(fi));
2943  fi.flags = O_CREAT | O_EXCL | O_WRONLY;
2944  err = fuse_fs_create(f->fs, path, mode, &fi);
2945  if (!err) {
2946  err = lookup_path(f, parent, name, path, &e,
2947  &fi);
2948  fuse_fs_release(f->fs, path, &fi);
2949  }
2950  }
2951  if (err == -ENOSYS) {
2952  err = fuse_fs_mknod(f->fs, path, mode, rdev);
2953  if (!err)
2954  err = lookup_path(f, parent, name, path, &e,
2955  NULL);
2956  }
2957  fuse_finish_interrupt(f, req, &d);
2958  free_path(f, parent, path);
2959  }
2960  reply_entry(req, &e, err);
2961 }
2962 
2963 static void fuse_lib_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
2964  mode_t mode)
2965 {
2966  struct fuse *f = req_fuse_prepare(req);
2967  struct fuse_entry_param e;
2968  char *path;
2969  int err;
2970 
2971  err = get_path_name(f, parent, name, &path);
2972  if (!err) {
2973  struct fuse_intr_data d;
2974 
2975  fuse_prepare_interrupt(f, req, &d);
2976  err = fuse_fs_mkdir(f->fs, path, mode);
2977  if (!err)
2978  err = lookup_path(f, parent, name, path, &e, NULL);
2979  fuse_finish_interrupt(f, req, &d);
2980  free_path(f, parent, path);
2981  }
2982  reply_entry(req, &e, err);
2983 }
2984 
2985 static void fuse_lib_unlink(fuse_req_t req, fuse_ino_t parent,
2986  const char *name)
2987 {
2988  struct fuse *f = req_fuse_prepare(req);
2989  struct node *wnode;
2990  char *path;
2991  int err;
2992 
2993  err = get_path_wrlock(f, parent, name, &path, &wnode);
2994  if (!err) {
2995  struct fuse_intr_data d;
2996 
2997  fuse_prepare_interrupt(f, req, &d);
2998  if (!f->conf.hard_remove && is_open(f, parent, name)) {
2999  err = hide_node(f, path, parent, name);
3000  } else {
3001  err = fuse_fs_unlink(f->fs, path);
3002  if (!err)
3003  remove_node(f, parent, name);
3004  }
3005  fuse_finish_interrupt(f, req, &d);
3006  free_path_wrlock(f, parent, wnode, path);
3007  }
3008  reply_err(req, err);
3009 }
3010 
3011 static void fuse_lib_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
3012 {
3013  struct fuse *f = req_fuse_prepare(req);
3014  struct node *wnode;
3015  char *path;
3016  int err;
3017 
3018  err = get_path_wrlock(f, parent, name, &path, &wnode);
3019  if (!err) {
3020  struct fuse_intr_data d;
3021 
3022  fuse_prepare_interrupt(f, req, &d);
3023  err = fuse_fs_rmdir(f->fs, path);
3024  fuse_finish_interrupt(f, req, &d);
3025  if (!err)
3026  remove_node(f, parent, name);
3027  free_path_wrlock(f, parent, wnode, path);
3028  }
3029  reply_err(req, err);
3030 }
3031 
3032 static void fuse_lib_symlink(fuse_req_t req, const char *linkname,
3033  fuse_ino_t parent, const char *name)
3034 {
3035  struct fuse *f = req_fuse_prepare(req);
3036  struct fuse_entry_param e;
3037  char *path;
3038  int err;
3039 
3040  err = get_path_name(f, parent, name, &path);
3041  if (!err) {
3042  struct fuse_intr_data d;
3043 
3044  fuse_prepare_interrupt(f, req, &d);
3045  err = fuse_fs_symlink(f->fs, linkname, path);
3046  if (!err)
3047  err = lookup_path(f, parent, name, path, &e, NULL);
3048  fuse_finish_interrupt(f, req, &d);
3049  free_path(f, parent, path);
3050  }
3051  reply_entry(req, &e, err);
3052 }
3053 
3054 static void fuse_lib_rename(fuse_req_t req, fuse_ino_t olddir,
3055  const char *oldname, fuse_ino_t newdir,
3056  const char *newname, unsigned int flags)
3057 {
3058  struct fuse *f = req_fuse_prepare(req);
3059  char *oldpath;
3060  char *newpath;
3061  struct node *wnode1;
3062  struct node *wnode2;
3063  int err;
3064 
3065  err = get_path2(f, olddir, oldname, newdir, newname,
3066  &oldpath, &newpath, &wnode1, &wnode2);
3067  if (!err) {
3068  struct fuse_intr_data d;
3069  err = 0;
3070  fuse_prepare_interrupt(f, req, &d);
3071  if (!f->conf.hard_remove && !(flags & RENAME_EXCHANGE) &&
3072  is_open(f, newdir, newname))
3073  err = hide_node(f, newpath, newdir, newname);
3074  if (!err) {
3075  err = fuse_fs_rename(f->fs, oldpath, newpath, flags);
3076  if (!err) {
3077  if (flags & RENAME_EXCHANGE) {
3078  err = exchange_node(f, olddir, oldname,
3079  newdir, newname);
3080  } else {
3081  err = rename_node(f, olddir, oldname,
3082  newdir, newname, 0);
3083  }
3084  }
3085  }
3086  fuse_finish_interrupt(f, req, &d);
3087  free_path2(f, olddir, newdir, wnode1, wnode2, oldpath, newpath);
3088  }
3089  reply_err(req, err);
3090 }
3091 
3092 static void fuse_lib_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
3093  const char *newname)
3094 {
3095  struct fuse *f = req_fuse_prepare(req);
3096  struct fuse_entry_param e;
3097  char *oldpath;
3098  char *newpath;
3099  int err;
3100 
3101  err = get_path2(f, ino, NULL, newparent, newname,
3102  &oldpath, &newpath, NULL, NULL);
3103  if (!err) {
3104  struct fuse_intr_data d;
3105 
3106  fuse_prepare_interrupt(f, req, &d);
3107  err = fuse_fs_link(f->fs, oldpath, newpath);
3108  if (!err)
3109  err = lookup_path(f, newparent, newname, newpath,
3110  &e, NULL);
3111  fuse_finish_interrupt(f, req, &d);
3112  free_path2(f, ino, newparent, NULL, NULL, oldpath, newpath);
3113  }
3114  reply_entry(req, &e, err);
3115 }
3116 
3117 static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
3118  struct fuse_file_info *fi)
3119 {
3120  struct node *node;
3121  int unlink_hidden = 0;
3122 
3123  fuse_fs_release(f->fs, path, fi);
3124 
3125  pthread_mutex_lock(&f->lock);
3126  node = get_node(f, ino);
3127  assert(node->open_count > 0);
3128  --node->open_count;
3129  if (node->is_hidden && !node->open_count) {
3130  unlink_hidden = 1;
3131  node->is_hidden = 0;
3132  }
3133  pthread_mutex_unlock(&f->lock);
3134 
3135  if(unlink_hidden) {
3136  if (path) {
3137  fuse_fs_unlink(f->fs, path);
3138  } else if (f->conf.nullpath_ok) {
3139  char *unlinkpath;
3140 
3141  if (get_path(f, ino, &unlinkpath) == 0)
3142  fuse_fs_unlink(f->fs, unlinkpath);
3143 
3144  free_path(f, ino, unlinkpath);
3145  }
3146  }
3147 }
3148 
3149 static void fuse_lib_create(fuse_req_t req, fuse_ino_t parent,
3150  const char *name, mode_t mode,
3151  struct fuse_file_info *fi)
3152 {
3153  struct fuse *f = req_fuse_prepare(req);
3154  struct fuse_intr_data d;
3155  struct fuse_entry_param e;
3156  char *path;
3157  int err;
3158 
3159  err = get_path_name(f, parent, name, &path);
3160  if (!err) {
3161  fuse_prepare_interrupt(f, req, &d);
3162  err = fuse_fs_create(f->fs, path, mode, fi);
3163  if (!err) {
3164  err = lookup_path(f, parent, name, path, &e, fi);
3165  if (err)
3166  fuse_fs_release(f->fs, path, fi);
3167  else if (!S_ISREG(e.attr.st_mode)) {
3168  err = -EIO;
3169  fuse_fs_release(f->fs, path, fi);
3170  forget_node(f, e.ino, 1);
3171  } else {
3172  if (f->conf.direct_io)
3173  fi->direct_io = 1;
3174  if (f->conf.kernel_cache)
3175  fi->keep_cache = 1;
3176 
3177  }
3178  }
3179  fuse_finish_interrupt(f, req, &d);
3180  }
3181  if (!err) {
3182  pthread_mutex_lock(&f->lock);
3183  get_node(f, e.ino)->open_count++;
3184  pthread_mutex_unlock(&f->lock);
3185  if (fuse_reply_create(req, &e, fi) == -ENOENT) {
3186  /* The open syscall was interrupted, so it
3187  must be cancelled */
3188  fuse_do_release(f, e.ino, path, fi);
3189  forget_node(f, e.ino, 1);
3190  }
3191  } else {
3192  reply_err(req, err);
3193  }
3194 
3195  free_path(f, parent, path);
3196 }
3197 
3198 static double diff_timespec(const struct timespec *t1,
3199  const struct timespec *t2)
3200 {
3201  return (t1->tv_sec - t2->tv_sec) +
3202  ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
3203 }
3204 
3205 static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path,
3206  struct fuse_file_info *fi)
3207 {
3208  struct node *node;
3209 
3210  pthread_mutex_lock(&f->lock);
3211  node = get_node(f, ino);
3212  if (node->cache_valid) {
3213  struct timespec now;
3214 
3215  curr_time(&now);
3216  if (diff_timespec(&now, &node->stat_updated) >
3217  f->conf.ac_attr_timeout) {
3218  struct stat stbuf;
3219  int err;
3220  pthread_mutex_unlock(&f->lock);
3221  err = fuse_fs_getattr(f->fs, path, &stbuf, fi);
3222  pthread_mutex_lock(&f->lock);
3223  if (!err)
3224  update_stat(node, &stbuf);
3225  else
3226  node->cache_valid = 0;
3227  }
3228  }
3229  if (node->cache_valid)
3230  fi->keep_cache = 1;
3231 
3232  node->cache_valid = 1;
3233  pthread_mutex_unlock(&f->lock);
3234 }
3235 
3236 static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
3237  struct fuse_file_info *fi)
3238 {
3239  struct fuse *f = req_fuse_prepare(req);
3240  struct fuse_intr_data d;
3241  char *path;
3242  int err;
3243 
3244  err = get_path(f, ino, &path);
3245  if (!err) {
3246  fuse_prepare_interrupt(f, req, &d);
3247  err = fuse_fs_open(f->fs, path, fi);
3248  if (!err) {
3249  if (f->conf.direct_io)
3250  fi->direct_io = 1;
3251  if (f->conf.kernel_cache)
3252  fi->keep_cache = 1;
3253 
3254  if (f->conf.auto_cache)
3255  open_auto_cache(f, ino, path, fi);
3256  }
3257  fuse_finish_interrupt(f, req, &d);
3258  }
3259  if (!err) {
3260  pthread_mutex_lock(&f->lock);
3261  get_node(f, ino)->open_count++;
3262  pthread_mutex_unlock(&f->lock);
3263  if (fuse_reply_open(req, fi) == -ENOENT) {
3264  /* The open syscall was interrupted, so it
3265  must be cancelled */
3266  fuse_do_release(f, ino, path, fi);
3267  }
3268  } else
3269  reply_err(req, err);
3270 
3271  free_path(f, ino, path);
3272 }
3273 
3274 static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
3275  off_t off, struct fuse_file_info *fi)
3276 {
3277  struct fuse *f = req_fuse_prepare(req);
3278  struct fuse_bufvec *buf = NULL;
3279  char *path;
3280  int res;
3281 
3282  res = get_path_nullok(f, ino, &path);
3283  if (res == 0) {
3284  struct fuse_intr_data d;
3285 
3286  fuse_prepare_interrupt(f, req, &d);
3287  res = fuse_fs_read_buf(f->fs, path, &buf, size, off, fi);
3288  fuse_finish_interrupt(f, req, &d);
3289  free_path(f, ino, path);
3290  }
3291 
3292  if (res == 0)
3294  else
3295  reply_err(req, res);
3296 
3297  fuse_free_buf(buf);
3298 }
3299 
3300 static void fuse_lib_write_buf(fuse_req_t req, fuse_ino_t ino,
3301  struct fuse_bufvec *buf, off_t off,
3302  struct fuse_file_info *fi)
3303 {
3304  struct fuse *f = req_fuse_prepare(req);
3305  char *path;
3306  int res;
3307 
3308  res = get_path_nullok(f, ino, &path);
3309  if (res == 0) {
3310  struct fuse_intr_data d;
3311 
3312  fuse_prepare_interrupt(f, req, &d);
3313  res = fuse_fs_write_buf(f->fs, path, buf, off, fi);
3314  fuse_finish_interrupt(f, req, &d);
3315  free_path(f, ino, path);
3316  }
3317 
3318  if (res >= 0)
3319  fuse_reply_write(req, res);
3320  else
3321  reply_err(req, res);
3322 }
3323 
3324 static void fuse_lib_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
3325  struct fuse_file_info *fi)
3326 {
3327  struct fuse *f = req_fuse_prepare(req);
3328  char *path;
3329  int err;
3330 
3331  err = get_path_nullok(f, ino, &path);
3332  if (!err) {
3333  struct fuse_intr_data d;
3334 
3335  fuse_prepare_interrupt(f, req, &d);
3336  err = fuse_fs_fsync(f->fs, path, datasync, fi);
3337  fuse_finish_interrupt(f, req, &d);
3338  free_path(f, ino, path);
3339  }
3340  reply_err(req, err);
3341 }
3342 
3343 static struct fuse_dh *get_dirhandle(const struct fuse_file_info *llfi,
3344  struct fuse_file_info *fi)
3345 {
3346  struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
3347  memset(fi, 0, sizeof(struct fuse_file_info));
3348  fi->fh = dh->fh;
3349  return dh;
3350 }
3351 
3352 static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
3353  struct fuse_file_info *llfi)
3354 {
3355  struct fuse *f = req_fuse_prepare(req);
3356  struct fuse_intr_data d;
3357  struct fuse_dh *dh;
3358  struct fuse_file_info fi;
3359  char *path;
3360  int err;
3361 
3362  dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
3363  if (dh == NULL) {
3364  reply_err(req, -ENOMEM);
3365  return;
3366  }
3367  memset(dh, 0, sizeof(struct fuse_dh));
3368  dh->fuse = f;
3369  dh->contents = NULL;
3370  dh->first = NULL;
3371  dh->len = 0;
3372  dh->filled = 0;
3373  dh->nodeid = ino;
3374  fuse_mutex_init(&dh->lock);
3375 
3376  llfi->fh = (uintptr_t) dh;
3377 
3378  memset(&fi, 0, sizeof(fi));
3379  fi.flags = llfi->flags;
3380 
3381  err = get_path(f, ino, &path);
3382  if (!err) {
3383  fuse_prepare_interrupt(f, req, &d);
3384  err = fuse_fs_opendir(f->fs, path, &fi);
3385  fuse_finish_interrupt(f, req, &d);
3386  dh->fh = fi.fh;
3387  }
3388  if (!err) {
3389  if (fuse_reply_open(req, llfi) == -ENOENT) {
3390  /* The opendir syscall was interrupted, so it
3391  must be cancelled */
3392  fuse_fs_releasedir(f->fs, path, &fi);
3393  pthread_mutex_destroy(&dh->lock);
3394  free(dh);
3395  }
3396  } else {
3397  reply_err(req, err);
3398  pthread_mutex_destroy(&dh->lock);
3399  free(dh);
3400  }
3401  free_path(f, ino, path);
3402 }
3403 
3404 static int extend_contents(struct fuse_dh *dh, unsigned minsize)
3405 {
3406  if (minsize > dh->size) {
3407  char *newptr;
3408  unsigned newsize = dh->size;
3409  if (!newsize)
3410  newsize = 1024;
3411  while (newsize < minsize) {
3412  if (newsize >= 0x80000000)
3413  newsize = 0xffffffff;
3414  else
3415  newsize *= 2;
3416  }
3417 
3418  newptr = (char *) realloc(dh->contents, newsize);
3419  if (!newptr) {
3420  dh->error = -ENOMEM;
3421  return -1;
3422  }
3423  dh->contents = newptr;
3424  dh->size = newsize;
3425  }
3426  return 0;
3427 }
3428 
3429 static int fuse_add_direntry_to_dh(struct fuse_dh *dh, const char *name,
3430  struct stat *st)
3431 {
3432  struct fuse_direntry *de;
3433 
3434  de = malloc(sizeof(struct fuse_direntry));
3435  if (!de) {
3436  dh->error = -ENOMEM;
3437  return -1;
3438  }
3439  de->name = strdup(name);
3440  if (!de->name) {
3441  dh->error = -ENOMEM;
3442  free(de);
3443  return -1;
3444  }
3445  de->stat = *st;
3446  de->next = NULL;
3447 
3448  *dh->last = de;
3449  dh->last = &de->next;
3450 
3451  return 0;
3452 }
3453 
3454 static fuse_ino_t lookup_nodeid(struct fuse *f, fuse_ino_t parent,
3455  const char *name)
3456 {
3457  struct node *node;
3458  fuse_ino_t res = FUSE_UNKNOWN_INO;
3459 
3460  pthread_mutex_lock(&f->lock);
3461  node = lookup_node(f, parent, name);
3462  if (node)
3463  res = node->nodeid;
3464  pthread_mutex_unlock(&f->lock);
3465 
3466  return res;
3467 }
3468 
3469 static int fill_dir(void *dh_, const char *name, const struct stat *statp,
3470  off_t off, enum fuse_fill_dir_flags flags)
3471 {
3472  struct fuse_dh *dh = (struct fuse_dh *) dh_;
3473  struct stat stbuf;
3474 
3475  if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3476  dh->error = -EIO;
3477  return 1;
3478  }
3479 
3480  if (statp)
3481  stbuf = *statp;
3482  else {
3483  memset(&stbuf, 0, sizeof(stbuf));
3484  stbuf.st_ino = FUSE_UNKNOWN_INO;
3485  }
3486 
3487  if (!dh->fuse->conf.use_ino) {
3488  stbuf.st_ino = FUSE_UNKNOWN_INO;
3489  if (dh->fuse->conf.readdir_ino) {
3490  stbuf.st_ino = (ino_t)
3491  lookup_nodeid(dh->fuse, dh->nodeid, name);
3492  }
3493  }
3494 
3495  if (off) {
3496  size_t newlen;
3497 
3498  if (dh->filled) {
3499  dh->error = -EIO;
3500  return 1;
3501  }
3502 
3503  if (dh->first) {
3504  dh->error = -EIO;
3505  return 1;
3506  }
3507 
3508  if (extend_contents(dh, dh->needlen) == -1)
3509  return 1;
3510 
3511  newlen = dh->len +
3512  fuse_add_direntry(dh->req, dh->contents + dh->len,
3513  dh->needlen - dh->len, name,
3514  &stbuf, off);
3515  if (newlen > dh->needlen)
3516  return 1;
3517 
3518  dh->len = newlen;
3519  } else {
3520  dh->filled = 1;
3521 
3522  if (fuse_add_direntry_to_dh(dh, name, &stbuf) == -1)
3523  return 1;
3524  }
3525  return 0;
3526 }
3527 
3528 static int is_dot_or_dotdot(const char *name)
3529 {
3530  return name[0] == '.' && (name[1] == '\0' ||
3531  (name[1] == '.' && name[2] == '\0'));
3532 }
3533 
3534 static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp,
3535  off_t off, enum fuse_fill_dir_flags flags)
3536 {
3537  struct fuse_dh *dh = (struct fuse_dh *) dh_;
3538  struct fuse_entry_param e = {
3539  /* ino=0 tells the kernel to ignore readdirplus stat info */
3540  .ino = 0,
3541  };
3542  struct fuse *f = dh->fuse;
3543  int res;
3544 
3545  if ((flags & ~FUSE_FILL_DIR_PLUS) != 0) {
3546  dh->error = -EIO;
3547  return 1;
3548  }
3549 
3550  if (off && statp && (flags & FUSE_FILL_DIR_PLUS)) {
3551  e.attr = *statp;
3552 
3553  if (!is_dot_or_dotdot(name)) {
3554  res = do_lookup(f, dh->nodeid, name, &e);
3555  if (res) {
3556  dh->error = res;
3557  return 1;
3558  }
3559  }
3560  } else {
3561  e.attr.st_ino = FUSE_UNKNOWN_INO;
3562  if (!f->conf.use_ino && f->conf.readdir_ino) {
3563  e.attr.st_ino = (ino_t)
3564  lookup_nodeid(f, dh->nodeid, name);
3565  }
3566  }
3567 
3568  if (off) {
3569  size_t newlen;
3570 
3571  if (dh->filled) {
3572  dh->error = -EIO;
3573  return 1;
3574  }
3575 
3576  if (dh->first) {
3577  dh->error = -EIO;
3578  return 1;
3579  }
3580  if (extend_contents(dh, dh->needlen) == -1)
3581  return 1;
3582 
3583  newlen = dh->len +
3584  fuse_add_direntry_plus(dh->req, dh->contents + dh->len,
3585  dh->needlen - dh->len, name,
3586  &e, off);
3587  if (newlen > dh->needlen)
3588  return 1;
3589  dh->len = newlen;
3590  } else {
3591  dh->filled = 1;
3592 
3593  if (fuse_add_direntry_to_dh(dh, name, &e.attr) == -1)
3594  return 1;
3595  }
3596 
3597  return 0;
3598 }
3599 
3600 static void free_direntries(struct fuse_direntry *de)
3601 {
3602  while (de) {
3603  struct fuse_direntry *next = de->next;
3604  free(de->name);
3605  free(de);
3606  de = next;
3607  }
3608 }
3609 
3610 static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3611  size_t size, off_t off, struct fuse_dh *dh,
3612  struct fuse_file_info *fi,
3613  enum fuse_readdir_flags flags)
3614 {
3615  char *path;
3616  int err;
3617 
3618  if (f->fs->op.readdir)
3619  err = get_path_nullok(f, ino, &path);
3620  else
3621  err = get_path(f, ino, &path);
3622  if (!err) {
3623  struct fuse_intr_data d;
3624  fuse_fill_dir_t filler = fill_dir;
3625 
3626  if (flags & FUSE_READDIR_PLUS)
3627  filler = fill_dir_plus;
3628 
3629  free_direntries(dh->first);
3630  dh->first = NULL;
3631  dh->last = &dh->first;
3632  dh->len = 0;
3633  dh->error = 0;
3634  dh->needlen = size;
3635  dh->filled = 0;
3636  dh->req = req;
3637  fuse_prepare_interrupt(f, req, &d);
3638  err = fuse_fs_readdir(f->fs, path, dh, filler, off, fi, flags);
3639  fuse_finish_interrupt(f, req, &d);
3640  dh->req = NULL;
3641  if (!err)
3642  err = dh->error;
3643  if (err)
3644  dh->filled = 0;
3645  free_path(f, ino, path);
3646  }
3647  return err;
3648 }
3649 
3650 static int readdir_fill_from_list(fuse_req_t req, struct fuse_dh *dh,
3651  off_t off, enum fuse_readdir_flags flags)
3652 {
3653  off_t pos;
3654  struct fuse_direntry *de = dh->first;
3655 
3656  dh->len = 0;
3657 
3658  if (extend_contents(dh, dh->needlen) == -1)
3659  return dh->error;
3660 
3661  for (pos = 0; pos < off; pos++) {
3662  if (!de)
3663  break;
3664 
3665  de = de->next;
3666  }
3667  while (de) {
3668  char *p = dh->contents + dh->len;
3669  unsigned rem = dh->needlen - dh->len;
3670  unsigned thislen;
3671  unsigned newlen;
3672  pos++;
3673 
3674  if (flags & FUSE_READDIR_PLUS) {
3675  struct fuse_entry_param e = {
3676  .ino = 0,
3677  .attr = de->stat,
3678  };
3679  thislen = fuse_add_direntry_plus(req, p, rem,
3680  de->name, &e, pos);
3681  } else {
3682  thislen = fuse_add_direntry(req, p, rem,
3683  de->name, &de->stat, pos);
3684  }
3685  newlen = dh->len + thislen;
3686  if (newlen > dh->needlen)
3687  break;
3688  dh->len = newlen;
3689  de = de->next;
3690  }
3691  return 0;
3692 }
3693 
3694 static void fuse_readdir_common(fuse_req_t req, fuse_ino_t ino, size_t size,
3695  off_t off, struct fuse_file_info *llfi,
3696  enum fuse_readdir_flags flags)
3697 {
3698  struct fuse *f = req_fuse_prepare(req);
3699  struct fuse_file_info fi;
3700  struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3701  int err;
3702 
3703  pthread_mutex_lock(&dh->lock);
3704  /* According to SUS, directory contents need to be refreshed on
3705  rewinddir() */
3706  if (!off)
3707  dh->filled = 0;
3708 
3709  if (!dh->filled) {
3710  err = readdir_fill(f, req, ino, size, off, dh, &fi, flags);
3711  if (err) {
3712  reply_err(req, err);
3713  goto out;
3714  }
3715  }
3716  if (dh->filled) {
3717  dh->needlen = size;
3718  err = readdir_fill_from_list(req, dh, off, flags);
3719  if (err) {
3720  reply_err(req, err);
3721  goto out;
3722  }
3723  }
3724  fuse_reply_buf(req, dh->contents, dh->len);
3725 out:
3726  pthread_mutex_unlock(&dh->lock);
3727 }
3728 
3729 static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
3730  off_t off, struct fuse_file_info *llfi)
3731 {
3732  fuse_readdir_common(req, ino, size, off, llfi, 0);
3733 }
3734 
3735 static void fuse_lib_readdirplus(fuse_req_t req, fuse_ino_t ino, size_t size,
3736  off_t off, struct fuse_file_info *llfi)
3737 {
3738  fuse_readdir_common(req, ino, size, off, llfi, FUSE_READDIR_PLUS);
3739 }
3740 
3741 static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
3742  struct fuse_file_info *llfi)
3743 {
3744  struct fuse *f = req_fuse_prepare(req);
3745  struct fuse_intr_data d;
3746  struct fuse_file_info fi;
3747  struct fuse_dh *dh = get_dirhandle(llfi, &fi);
3748  char *path;
3749 
3750  get_path_nullok(f, ino, &path);
3751 
3752  fuse_prepare_interrupt(f, req, &d);
3753  fuse_fs_releasedir(f->fs, path, &fi);
3754  fuse_finish_interrupt(f, req, &d);
3755  free_path(f, ino, path);
3756 
3757  pthread_mutex_lock(&dh->lock);
3758  pthread_mutex_unlock(&dh->lock);
3759  pthread_mutex_destroy(&dh->lock);
3760  free_direntries(dh->first);
3761  free(dh->contents);
3762  free(dh);
3763  reply_err(req, 0);
3764 }
3765 
3766 static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
3767  struct fuse_file_info *llfi)
3768 {
3769  struct fuse *f = req_fuse_prepare(req);
3770  struct fuse_file_info fi;
3771  char *path;
3772  int err;
3773 
3774  get_dirhandle(llfi, &fi);
3775 
3776  err = get_path_nullok(f, ino, &path);
3777  if (!err) {
3778  struct fuse_intr_data d;
3779  fuse_prepare_interrupt(f, req, &d);
3780  err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
3781  fuse_finish_interrupt(f, req, &d);
3782  free_path(f, ino, path);
3783  }
3784  reply_err(req, err);
3785 }
3786 
3787 static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
3788 {
3789  struct fuse *f = req_fuse_prepare(req);
3790  struct statvfs buf;
3791  char *path = NULL;
3792  int err = 0;
3793 
3794  memset(&buf, 0, sizeof(buf));
3795  if (ino)
3796  err = get_path(f, ino, &path);
3797 
3798  if (!err) {
3799  struct fuse_intr_data d;
3800  fuse_prepare_interrupt(f, req, &d);
3801  err = fuse_fs_statfs(f->fs, path ? path : "/", &buf);
3802  fuse_finish_interrupt(f, req, &d);
3803  free_path(f, ino, path);
3804  }
3805 
3806  if (!err)
3807  fuse_reply_statfs(req, &buf);
3808  else
3809  reply_err(req, err);
3810 }
3811 
3812 static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3813  const char *value, size_t size, int flags)
3814 {
3815  struct fuse *f = req_fuse_prepare(req);
3816  char *path;
3817  int err;
3818 
3819  err = get_path(f, ino, &path);
3820  if (!err) {
3821  struct fuse_intr_data d;
3822  fuse_prepare_interrupt(f, req, &d);
3823  err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
3824  fuse_finish_interrupt(f, req, &d);
3825  free_path(f, ino, path);
3826  }
3827  reply_err(req, err);
3828 }
3829 
3830 static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3831  const char *name, char *value, size_t size)
3832 {
3833  int err;
3834  char *path;
3835 
3836  err = get_path(f, ino, &path);
3837  if (!err) {
3838  struct fuse_intr_data d;
3839  fuse_prepare_interrupt(f, req, &d);
3840  err = fuse_fs_getxattr(f->fs, path, name, value, size);
3841  fuse_finish_interrupt(f, req, &d);
3842  free_path(f, ino, path);
3843  }
3844  return err;
3845 }
3846 
3847 static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3848  size_t size)
3849 {
3850  struct fuse *f = req_fuse_prepare(req);
3851  int res;
3852 
3853  if (size) {
3854  char *value = (char *) malloc(size);
3855  if (value == NULL) {
3856  reply_err(req, -ENOMEM);
3857  return;
3858  }
3859  res = common_getxattr(f, req, ino, name, value, size);
3860  if (res > 0)
3861  fuse_reply_buf(req, value, res);
3862  else
3863  reply_err(req, res);
3864  free(value);
3865  } else {
3866  res = common_getxattr(f, req, ino, name, NULL, 0);
3867  if (res >= 0)
3868  fuse_reply_xattr(req, res);
3869  else
3870  reply_err(req, res);
3871  }
3872 }
3873 
3874 static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
3875  char *list, size_t size)
3876 {
3877  char *path;
3878  int err;
3879 
3880  err = get_path(f, ino, &path);
3881  if (!err) {
3882  struct fuse_intr_data d;
3883  fuse_prepare_interrupt(f, req, &d);
3884  err = fuse_fs_listxattr(f->fs, path, list, size);
3885  fuse_finish_interrupt(f, req, &d);
3886  free_path(f, ino, path);
3887  }
3888  return err;
3889 }
3890 
3891 static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
3892 {
3893  struct fuse *f = req_fuse_prepare(req);
3894  int res;
3895 
3896  if (size) {
3897  char *list = (char *) malloc(size);
3898  if (list == NULL) {
3899  reply_err(req, -ENOMEM);
3900  return;
3901  }
3902  res = common_listxattr(f, req, ino, list, size);
3903  if (res > 0)
3904  fuse_reply_buf(req, list, res);
3905  else
3906  reply_err(req, res);
3907  free(list);
3908  } else {
3909  res = common_listxattr(f, req, ino, NULL, 0);
3910  if (res >= 0)
3911  fuse_reply_xattr(req, res);
3912  else
3913  reply_err(req, res);
3914  }
3915 }
3916 
3917 static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
3918  const char *name)
3919 {
3920  struct fuse *f = req_fuse_prepare(req);
3921  char *path;
3922  int err;
3923 
3924  err = get_path(f, ino, &path);
3925  if (!err) {
3926  struct fuse_intr_data d;
3927  fuse_prepare_interrupt(f, req, &d);
3928  err = fuse_fs_removexattr(f->fs, path, name);
3929  fuse_finish_interrupt(f, req, &d);
3930  free_path(f, ino, path);
3931  }
3932  reply_err(req, err);
3933 }
3934 
3935 static struct lock *locks_conflict(struct node *node, const struct lock *lock)
3936 {
3937  struct lock *l;
3938 
3939  for (l = node->locks; l; l = l->next)
3940  if (l->owner != lock->owner &&
3941  lock->start <= l->end && l->start <= lock->end &&
3942  (l->type == F_WRLCK || lock->type == F_WRLCK))
3943  break;
3944 
3945  return l;
3946 }
3947 
3948 static void delete_lock(struct lock **lockp)
3949 {
3950  struct lock *l = *lockp;
3951  *lockp = l->next;
3952  free(l);
3953 }
3954 
3955 static void insert_lock(struct lock **pos, struct lock *lock)
3956 {
3957  lock->next = *pos;
3958  *pos = lock;
3959 }
3960 
3961 static int locks_insert(struct node *node, struct lock *lock)
3962 {
3963  struct lock **lp;
3964  struct lock *newl1 = NULL;
3965  struct lock *newl2 = NULL;
3966 
3967  if (lock->type != F_UNLCK || lock->start != 0 ||
3968  lock->end != OFFSET_MAX) {
3969  newl1 = malloc(sizeof(struct lock));
3970  newl2 = malloc(sizeof(struct lock));
3971 
3972  if (!newl1 || !newl2) {
3973  free(newl1);
3974  free(newl2);
3975  return -ENOLCK;
3976  }
3977  }
3978 
3979  for (lp = &node->locks; *lp;) {
3980  struct lock *l = *lp;
3981  if (l->owner != lock->owner)
3982  goto skip;
3983 
3984  if (lock->type == l->type) {
3985  if (l->end < lock->start - 1)
3986  goto skip;
3987  if (lock->end < l->start - 1)
3988  break;
3989  if (l->start <= lock->start && lock->end <= l->end)
3990  goto out;
3991  if (l->start < lock->start)
3992  lock->start = l->start;
3993  if (lock->end < l->end)
3994  lock->end = l->end;
3995  goto delete;
3996  } else {
3997  if (l->end < lock->start)
3998  goto skip;
3999  if (lock->end < l->start)
4000  break;
4001  if (lock->start <= l->start && l->end <= lock->end)
4002  goto delete;
4003  if (l->end <= lock->end) {
4004  l->end = lock->start - 1;
4005  goto skip;
4006  }
4007  if (lock->start <= l->start) {
4008  l->start = lock->end + 1;
4009  break;
4010  }
4011  *newl2 = *l;
4012  newl2->start = lock->end + 1;
4013  l->end = lock->start - 1;
4014  insert_lock(&l->next, newl2);
4015  newl2 = NULL;
4016  }
4017  skip:
4018  lp = &l->next;
4019  continue;
4020 
4021  delete:
4022  delete_lock(lp);
4023  }
4024  if (lock->type != F_UNLCK) {
4025  *newl1 = *lock;
4026  insert_lock(lp, newl1);
4027  newl1 = NULL;
4028  }
4029 out:
4030  free(newl1);
4031  free(newl2);
4032  return 0;
4033 }
4034 
4035 static void flock_to_lock(struct flock *flock, struct lock *lock)
4036 {
4037  memset(lock, 0, sizeof(struct lock));
4038  lock->type = flock->l_type;
4039  lock->start = flock->l_start;
4040  lock->end =
4041  flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
4042  lock->pid = flock->l_pid;
4043 }
4044 
4045 static void lock_to_flock(struct lock *lock, struct flock *flock)
4046 {
4047  flock->l_type = lock->type;
4048  flock->l_start = lock->start;
4049  flock->l_len =
4050  (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
4051  flock->l_pid = lock->pid;
4052 }
4053 
4054 static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
4055  const char *path, struct fuse_file_info *fi)
4056 {
4057  struct fuse_intr_data d;
4058  struct flock lock;
4059  struct lock l;
4060  int err;
4061  int errlock;
4062 
4063  fuse_prepare_interrupt(f, req, &d);
4064  memset(&lock, 0, sizeof(lock));
4065  lock.l_type = F_UNLCK;
4066  lock.l_whence = SEEK_SET;
4067  err = fuse_fs_flush(f->fs, path, fi);
4068  errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
4069  fuse_finish_interrupt(f, req, &d);
4070 
4071  if (errlock != -ENOSYS) {
4072  flock_to_lock(&lock, &l);
4073  l.owner = fi->lock_owner;
4074  pthread_mutex_lock(&f->lock);
4075  locks_insert(get_node(f, ino), &l);
4076  pthread_mutex_unlock(&f->lock);
4077 
4078  /* if op.lock() is defined FLUSH is needed regardless
4079  of op.flush() */
4080  if (err == -ENOSYS)
4081  err = 0;
4082  }
4083  return err;
4084 }
4085 
4086 static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
4087  struct fuse_file_info *fi)
4088 {
4089  struct fuse *f = req_fuse_prepare(req);
4090  struct fuse_intr_data d;
4091  char *path;
4092  int err = 0;
4093 
4094  get_path_nullok(f, ino, &path);
4095  if (fi->flush) {
4096  err = fuse_flush_common(f, req, ino, path, fi);
4097  if (err == -ENOSYS)
4098  err = 0;
4099  }
4100 
4101  fuse_prepare_interrupt(f, req, &d);
4102  fuse_do_release(f, ino, path, fi);
4103  fuse_finish_interrupt(f, req, &d);
4104  free_path(f, ino, path);
4105 
4106  reply_err(req, err);
4107 }
4108 
4109 static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
4110  struct fuse_file_info *fi)
4111 {
4112  struct fuse *f = req_fuse_prepare(req);
4113  char *path;
4114  int err;
4115 
4116  get_path_nullok(f, ino, &path);
4117  err = fuse_flush_common(f, req, ino, path, fi);
4118  free_path(f, ino, path);
4119 
4120  reply_err(req, err);
4121 }
4122 
4123 static int fuse_lock_common(fuse_req_t req, fuse_ino_t ino,
4124  struct fuse_file_info *fi, struct flock *lock,
4125  int cmd)
4126 {
4127  struct fuse *f = req_fuse_prepare(req);
4128  char *path;
4129  int err;
4130 
4131  err = get_path_nullok(f, ino, &path);
4132  if (!err) {
4133  struct fuse_intr_data d;
4134  fuse_prepare_interrupt(f, req, &d);
4135  err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
4136  fuse_finish_interrupt(f, req, &d);
4137  free_path(f, ino, path);
4138  }
4139  return err;
4140 }
4141 
4142 static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
4143  struct fuse_file_info *fi, struct flock *lock)
4144 {
4145  int err;
4146  struct lock l;
4147  struct lock *conflict;
4148  struct fuse *f = req_fuse(req);
4149 
4150  flock_to_lock(lock, &l);
4151  l.owner = fi->lock_owner;
4152  pthread_mutex_lock(&f->lock);
4153  conflict = locks_conflict(get_node(f, ino), &l);
4154  if (conflict)
4155  lock_to_flock(conflict, lock);
4156  pthread_mutex_unlock(&f->lock);
4157  if (!conflict)
4158  err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
4159  else
4160  err = 0;
4161 
4162  if (!err)
4163  fuse_reply_lock(req, lock);
4164  else
4165  reply_err(req, err);
4166 }
4167 
4168 static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
4169  struct fuse_file_info *fi, struct flock *lock,
4170  int sleep)
4171 {
4172  int err = fuse_lock_common(req, ino, fi, lock,
4173  sleep ? F_SETLKW : F_SETLK);
4174  if (!err) {
4175  struct fuse *f = req_fuse(req);
4176  struct lock l;
4177  flock_to_lock(lock, &l);
4178  l.owner = fi->lock_owner;
4179  pthread_mutex_lock(&f->lock);
4180  locks_insert(get_node(f, ino), &l);
4181  pthread_mutex_unlock(&f->lock);
4182  }
4183  reply_err(req, err);
4184 }
4185 
4186 static void fuse_lib_flock(fuse_req_t req, fuse_ino_t ino,
4187  struct fuse_file_info *fi, int op)
4188 {
4189  struct fuse *f = req_fuse_prepare(req);
4190  char *path;
4191  int err;
4192 
4193  err = get_path_nullok(f, ino, &path);
4194  if (err == 0) {
4195  struct fuse_intr_data d;
4196  fuse_prepare_interrupt(f, req, &d);
4197  err = fuse_fs_flock(f->fs, path, fi, op);
4198  fuse_finish_interrupt(f, req, &d);
4199  free_path(f, ino, path);
4200  }
4201  reply_err(req, err);
4202 }
4203 
4204 static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
4205  uint64_t idx)
4206 {
4207  struct fuse *f = req_fuse_prepare(req);
4208  struct fuse_intr_data d;
4209  char *path;
4210  int err;
4211 
4212  err = get_path(f, ino, &path);
4213  if (!err) {
4214  fuse_prepare_interrupt(f, req, &d);
4215  err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
4216  fuse_finish_interrupt(f, req, &d);
4217  free_path(f, ino, path);
4218  }
4219  if (!err)
4220  fuse_reply_bmap(req, idx);
4221  else
4222  reply_err(req, err);
4223 }
4224 
4225 static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
4226  struct fuse_file_info *llfi, unsigned int flags,
4227  const void *in_buf, size_t in_bufsz,
4228  size_t out_bufsz)
4229 {
4230  struct fuse *f = req_fuse_prepare(req);
4231  struct fuse_intr_data d;
4232  struct fuse_file_info fi;
4233  char *path, *out_buf = NULL;
4234  int err;
4235 
4236  err = -EPERM;
4237  if (flags & FUSE_IOCTL_UNRESTRICTED)
4238  goto err;
4239 
4240  if (flags & FUSE_IOCTL_DIR)
4241  get_dirhandle(llfi, &fi);
4242  else
4243  fi = *llfi;
4244 
4245  if (out_bufsz) {
4246  err = -ENOMEM;
4247  out_buf = malloc(out_bufsz);
4248  if (!out_buf)
4249  goto err;
4250  }
4251 
4252  assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
4253  if (out_buf && in_bufsz)
4254  memcpy(out_buf, in_buf, in_bufsz);
4255 
4256  err = get_path_nullok(f, ino, &path);
4257  if (err)
4258  goto err;
4259 
4260  fuse_prepare_interrupt(f, req, &d);
4261 
4262  err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
4263  out_buf ?: (void *)in_buf);
4264 
4265  fuse_finish_interrupt(f, req, &d);
4266  free_path(f, ino, path);
4267 
4268  fuse_reply_ioctl(req, err, out_buf, out_bufsz);
4269  goto out;
4270 err:
4271  reply_err(req, err);
4272 out:
4273  free(out_buf);
4274 }
4275 
4276 static void fuse_lib_poll(fuse_req_t req, fuse_ino_t ino,
4277  struct fuse_file_info *fi, struct fuse_pollhandle *ph)
4278 {
4279  struct fuse *f = req_fuse_prepare(req);
4280  struct fuse_intr_data d;
4281  char *path;
4282  int err;
4283  unsigned revents = 0;
4284 
4285  err = get_path_nullok(f, ino, &path);
4286  if (!err) {
4287  fuse_prepare_interrupt(f, req, &d);
4288  err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
4289  fuse_finish_interrupt(f, req, &d);
4290  free_path(f, ino, path);
4291  }
4292  if (!err)
4293  fuse_reply_poll(req, revents);
4294  else
4295  reply_err(req, err);
4296 }
4297 
4298 static void fuse_lib_fallocate(fuse_req_t req, fuse_ino_t ino, int mode,
4299  off_t offset, off_t length, struct fuse_file_info *fi)
4300 {
4301  struct fuse *f = req_fuse_prepare(req);
4302  struct fuse_intr_data d;
4303  char *path;
4304  int err;
4305 
4306  err = get_path_nullok(f, ino, &path);
4307  if (!err) {
4308  fuse_prepare_interrupt(f, req, &d);
4309  err = fuse_fs_fallocate(f->fs, path, mode, offset, length, fi);
4310  fuse_finish_interrupt(f, req, &d);
4311  free_path(f, ino, path);
4312  }
4313  reply_err(req, err);
4314 }
4315 
4316 static void fuse_lib_copy_file_range(fuse_req_t req, fuse_ino_t nodeid_in,
4317  off_t off_in, struct fuse_file_info *fi_in,
4318  fuse_ino_t nodeid_out, off_t off_out,
4319  struct fuse_file_info *fi_out, size_t len,
4320  int flags)
4321 {
4322  struct fuse *f = req_fuse_prepare(req);
4323  struct fuse_intr_data d;
4324  char *path_in, *path_out;
4325  int err;
4326  ssize_t res;
4327 
4328  err = get_path_nullok(f, nodeid_in, &path_in);
4329  if (err) {
4330  reply_err(req, err);
4331  return;
4332  }
4333 
4334  err = get_path_nullok(f, nodeid_out, &path_out);
4335  if (err) {
4336  free_path(f, nodeid_in, path_in);
4337  reply_err(req, err);
4338  return;
4339  }
4340 
4341  fuse_prepare_interrupt(f, req, &d);
4342  res = fuse_fs_copy_file_range(f->fs, path_in, fi_in, off_in, path_out,
4343  fi_out, off_out, len, flags);
4344  fuse_finish_interrupt(f, req, &d);
4345 
4346  if (res >= 0)
4347  fuse_reply_write(req, res);
4348  else
4349  reply_err(req, res);
4350 
4351  free_path(f, nodeid_in, path_in);
4352  free_path(f, nodeid_out, path_out);
4353 }
4354 
4355 static int clean_delay(struct fuse *f)
4356 {
4357  /*
4358  * This is calculating the delay between clean runs. To
4359  * reduce the number of cleans we are doing them 10 times
4360  * within the remember window.
4361  */
4362  int min_sleep = 60;
4363  int max_sleep = 3600;
4364  int sleep_time = f->conf.remember / 10;
4365 
4366  if (sleep_time > max_sleep)
4367  return max_sleep;
4368  if (sleep_time < min_sleep)
4369  return min_sleep;
4370  return sleep_time;
4371 }
4372 
4373 int fuse_clean_cache(struct fuse *f)
4374 {
4375  struct node_lru *lnode;
4376  struct list_head *curr, *next;
4377  struct node *node;
4378  struct timespec now;
4379 
4380  pthread_mutex_lock(&f->lock);
4381 
4382  curr_time(&now);
4383 
4384  for (curr = f->lru_table.next; curr != &f->lru_table; curr = next) {
4385  double age;
4386 
4387  next = curr->next;
4388  lnode = list_entry(curr, struct node_lru, lru);
4389  node = &lnode->node;
4390 
4391  age = diff_timespec(&now, &lnode->forget_time);
4392  if (age <= f->conf.remember)
4393  break;
4394 
4395  assert(node->nlookup == 1);
4396 
4397  /* Don't forget active directories */
4398  if (node->refctr > 1)
4399  continue;
4400 
4401  node->nlookup = 0;
4402  unhash_name(f, node);
4403  unref_node(f, node);
4404  }
4405  pthread_mutex_unlock(&f->lock);
4406 
4407  return clean_delay(f);
4408 }
4409 
4410 static struct fuse_lowlevel_ops fuse_path_ops = {
4411  .init = fuse_lib_init,
4412  .destroy = fuse_lib_destroy,
4413  .lookup = fuse_lib_lookup,
4414  .forget = fuse_lib_forget,
4415  .forget_multi = fuse_lib_forget_multi,
4416  .getattr = fuse_lib_getattr,
4417  .setattr = fuse_lib_setattr,
4418  .access = fuse_lib_access,
4419  .readlink = fuse_lib_readlink,
4420  .mknod = fuse_lib_mknod,
4421  .mkdir = fuse_lib_mkdir,
4422  .unlink = fuse_lib_unlink,
4423  .rmdir = fuse_lib_rmdir,
4424  .symlink = fuse_lib_symlink,
4425  .rename = fuse_lib_rename,
4426  .link = fuse_lib_link,
4427  .create = fuse_lib_create,
4428  .open = fuse_lib_open,
4429  .read = fuse_lib_read,
4430  .write_buf = fuse_lib_write_buf,
4431  .flush = fuse_lib_flush,
4432  .release = fuse_lib_release,
4433  .fsync = fuse_lib_fsync,
4434  .opendir = fuse_lib_opendir,
4435  .readdir = fuse_lib_readdir,
4436  .readdirplus = fuse_lib_readdirplus,
4437  .releasedir = fuse_lib_releasedir,
4438  .fsyncdir = fuse_lib_fsyncdir,
4439  .statfs = fuse_lib_statfs,
4440  .setxattr = fuse_lib_setxattr,
4441  .getxattr = fuse_lib_getxattr,
4442  .listxattr = fuse_lib_listxattr,
4443  .removexattr = fuse_lib_removexattr,
4444  .getlk = fuse_lib_getlk,
4445  .setlk = fuse_lib_setlk,
4446  .flock = fuse_lib_flock,
4447  .bmap = fuse_lib_bmap,
4448  .ioctl = fuse_lib_ioctl,
4449  .poll = fuse_lib_poll,
4450  .fallocate = fuse_lib_fallocate,
4451  .copy_file_range = fuse_lib_copy_file_range,
4452 };
4453 
4454 int fuse_notify_poll(struct fuse_pollhandle *ph)
4455 {
4456  return fuse_lowlevel_notify_poll(ph);
4457 }
4458 
4459 struct fuse_session *fuse_get_session(struct fuse *f)
4460 {
4461  return f->se;
4462 }
4463 
4464 static int fuse_session_loop_remember(struct fuse *f)
4465 {
4466  struct fuse_session *se = f->se;
4467  int res = 0;
4468  struct timespec now;
4469  time_t next_clean;
4470  struct pollfd fds = {
4471  .fd = se->fd,
4472  .events = POLLIN
4473  };
4474  struct fuse_buf fbuf = {
4475  .mem = NULL,
4476  };
4477 
4478  curr_time(&now);
4479  next_clean = now.tv_sec;
4480  while (!fuse_session_exited(se)) {
4481  unsigned timeout;
4482 
4483  curr_time(&now);
4484  if (now.tv_sec < next_clean)
4485  timeout = next_clean - now.tv_sec;
4486  else
4487  timeout = 0;
4488 
4489  res = poll(&fds, 1, timeout * 1000);
4490  if (res == -1) {
4491  if (errno == -EINTR)
4492  continue;
4493  else
4494  break;
4495  } else if (res > 0) {
4496  res = fuse_session_receive_buf_int(se, &fbuf, NULL);
4497 
4498  if (res == -EINTR)
4499  continue;
4500  if (res <= 0)
4501  break;
4502 
4503  fuse_session_process_buf_int(se, &fbuf, NULL);
4504  } else {
4505  timeout = fuse_clean_cache(f);
4506  curr_time(&now);
4507  next_clean = now.tv_sec + timeout;
4508  }
4509  }
4510 
4511  free(fbuf.mem);
4512  fuse_session_reset(se);
4513  return res < 0 ? -1 : 0;
4514 }
4515 
4516 int fuse_loop(struct fuse *f)
4517 {
4518  if (!f)
4519  return -1;
4520 
4521  if (lru_enabled(f))
4522  return fuse_session_loop_remember(f);
4523 
4524  return fuse_session_loop(f->se);
4525 }
4526 
4527 FUSE_SYMVER(".symver fuse_loop_mt_32,fuse_loop_mt@@FUSE_3.2");
4528 int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config)
4529 {
4530  if (f == NULL)
4531  return -1;
4532 
4533  int res = fuse_start_cleanup_thread(f);
4534  if (res)
4535  return -1;
4536 
4537  res = fuse_session_loop_mt_32(fuse_get_session(f), config);
4539  return res;
4540 }
4541 
4542 int fuse_loop_mt_31(struct fuse *f, int clone_fd);
4543 FUSE_SYMVER(".symver fuse_loop_mt_31,fuse_loop_mt@FUSE_3.0");
4544 int fuse_loop_mt_31(struct fuse *f, int clone_fd)
4545 {
4546  struct fuse_loop_config config;
4547  config.clone_fd = clone_fd;
4548  config.max_idle_threads = 10;
4549  return fuse_loop_mt_32(f, &config);
4550 }
4551 
4552 void fuse_exit(struct fuse *f)
4553 {
4554  fuse_session_exit(f->se);
4555 }
4556 
4558 {
4559  struct fuse_context_i *c = fuse_get_context_internal();
4560 
4561  if (c)
4562  return &c->ctx;
4563  else
4564  return NULL;
4565 }
4566 
4567 int fuse_getgroups(int size, gid_t list[])
4568 {
4569  struct fuse_context_i *c = fuse_get_context_internal();
4570  if (!c)
4571  return -EINVAL;
4572 
4573  return fuse_req_getgroups(c->req, size, list);
4574 }
4575 
4577 {
4578  struct fuse_context_i *c = fuse_get_context_internal();
4579 
4580  if (c)
4581  return fuse_req_interrupted(c->req);
4582  else
4583  return 0;
4584 }
4585 
4586 int fuse_invalidate_path(struct fuse *f, const char *path) {
4587  fuse_ino_t ino;
4588  int err = lookup_path_in_cache(f, path, &ino);
4589  if (err) {
4590  return err;
4591  }
4592 
4593  return fuse_lowlevel_notify_inval_inode(f->se, ino, 0, 0);
4594 }
4595 
4596 #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
4597 
4598 static const struct fuse_opt fuse_lib_opts[] = {
4599  FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
4601  FUSE_LIB_OPT("debug", debug, 1),
4602  FUSE_LIB_OPT("-d", debug, 1),
4603  FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
4604  FUSE_LIB_OPT("auto_cache", auto_cache, 1),
4605  FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
4606  FUSE_LIB_OPT("umask=", set_mode, 1),
4607  FUSE_LIB_OPT("umask=%o", umask, 0),
4608  FUSE_LIB_OPT("uid=", set_uid, 1),
4609  FUSE_LIB_OPT("uid=%d", uid, 0),
4610  FUSE_LIB_OPT("gid=", set_gid, 1),
4611  FUSE_LIB_OPT("gid=%d", gid, 0),
4612  FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
4613  FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
4614  FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
4615  FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
4616  FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
4617  FUSE_LIB_OPT("noforget", remember, -1),
4618  FUSE_LIB_OPT("remember=%u", remember, 0),
4619  FUSE_LIB_OPT("modules=%s", modules, 0),
4620  FUSE_OPT_END
4621 };
4622 
4623 static int fuse_lib_opt_proc(void *data, const char *arg, int key,
4624  struct fuse_args *outargs)
4625 {
4626  (void) arg; (void) outargs; (void) data; (void) key;
4627 
4628  /* Pass through unknown options */
4629  return 1;
4630 }
4631 
4632 
4633 static const struct fuse_opt fuse_help_opts[] = {
4634  FUSE_LIB_OPT("modules=%s", modules, 1),
4635  FUSE_OPT_KEY("modules=%s", FUSE_OPT_KEY_KEEP),
4636  FUSE_OPT_END
4637 };
4638 
4639 static void print_module_help(const char *name,
4640  fuse_module_factory_t *fac)
4641 {
4642  struct fuse_args a = FUSE_ARGS_INIT(0, NULL);
4643  if (fuse_opt_add_arg(&a, "") == -1 ||
4644  fuse_opt_add_arg(&a, "-h") == -1)
4645  return;
4646  printf("\nOptions for %s module:\n", name);
4647  (*fac)(&a, NULL);
4648 }
4649 
4650 void fuse_lib_help(struct fuse_args *args)
4651 {
4652  /* These are not all options, but only the ones that
4653  may be of interest to an end-user */
4654  printf(
4655 " -o kernel_cache cache files in kernel\n"
4656 " -o [no]auto_cache enable caching based on modification times (off)\n"
4657 " -o umask=M set file permissions (octal)\n"
4658 " -o uid=N set file owner\n"
4659 " -o gid=N set file group\n"
4660 " -o entry_timeout=T cache timeout for names (1.0s)\n"
4661 " -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
4662 " -o attr_timeout=T cache timeout for attributes (1.0s)\n"
4663 " -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
4664 " -o noforget never forget cached inodes\n"
4665 " -o remember=T remember cached inodes for T seconds (0s)\n"
4666 " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n");
4667 
4668 
4669  /* Print low-level help */
4671 
4672  /* Print help for builtin modules */
4673  print_module_help("subdir", &fuse_module_subdir_factory);
4674 #ifdef HAVE_ICONV
4675  print_module_help("iconv", &fuse_module_iconv_factory);
4676 #endif
4677 
4678  /* Parse command line options in case we need to
4679  activate more modules */
4680  struct fuse_config conf = { .modules = NULL };
4681  if (fuse_opt_parse(args, &conf, fuse_help_opts,
4682  fuse_lib_opt_proc) == -1
4683  || !conf.modules)
4684  return;
4685 
4686  char *module;
4687  char *next;
4688  struct fuse_module *m;
4689 
4690  // Iterate over all modules
4691  for (module = conf.modules; module; module = next) {
4692  char *p;
4693  for (p = module; *p && *p != ':'; p++);
4694  next = *p ? p + 1 : NULL;
4695  *p = '\0';
4696 
4697  m = fuse_get_module(module);
4698  if (m)
4699  print_module_help(module, &m->factory);
4700  }
4701 }
4702 
4703 
4704 
4705 static int fuse_init_intr_signal(int signum, int *installed)
4706 {
4707  struct sigaction old_sa;
4708 
4709  if (sigaction(signum, NULL, &old_sa) == -1) {
4710  perror("fuse: cannot get old signal handler");
4711  return -1;
4712  }
4713 
4714  if (old_sa.sa_handler == SIG_DFL) {
4715  struct sigaction sa;
4716 
4717  memset(&sa, 0, sizeof(struct sigaction));
4718  sa.sa_handler = fuse_intr_sighandler;
4719  sigemptyset(&sa.sa_mask);
4720 
4721  if (sigaction(signum, &sa, NULL) == -1) {
4722  perror("fuse: cannot set interrupt signal handler");
4723  return -1;
4724  }
4725  *installed = 1;
4726  }
4727  return 0;
4728 }
4729 
4730 static void fuse_restore_intr_signal(int signum)
4731 {
4732  struct sigaction sa;
4733 
4734  memset(&sa, 0, sizeof(struct sigaction));
4735  sa.sa_handler = SIG_DFL;
4736  sigaction(signum, &sa, NULL);
4737 }
4738 
4739 
4740 static int fuse_push_module(struct fuse *f, const char *module,
4741  struct fuse_args *args)
4742 {
4743  struct fuse_fs *fs[2] = { f->fs, NULL };
4744  struct fuse_fs *newfs;
4745  struct fuse_module *m = fuse_get_module(module);
4746 
4747  if (!m)
4748  return -1;
4749 
4750  newfs = m->factory(args, fs);
4751  if (!newfs) {
4752  fuse_put_module(m);
4753  return -1;
4754  }
4755  newfs->m = m;
4756  f->fs = newfs;
4757  return 0;
4758 }
4759 
4760 struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
4761  void *user_data)
4762 {
4763  struct fuse_fs *fs;
4764 
4765  if (sizeof(struct fuse_operations) < op_size) {
4766  fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
4767  op_size = sizeof(struct fuse_operations);
4768  }
4769 
4770  fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
4771  if (!fs) {
4772  fprintf(stderr, "fuse: failed to allocate fuse_fs object\n");
4773  return NULL;
4774  }
4775 
4776  fs->user_data = user_data;
4777  if (op)
4778  memcpy(&fs->op, op, op_size);
4779  return fs;
4780 }
4781 
4782 static int node_table_init(struct node_table *t)
4783 {
4784  t->size = NODE_TABLE_MIN_SIZE;
4785  t->array = (struct node **) calloc(1, sizeof(struct node *) * t->size);
4786  if (t->array == NULL) {
4787  fprintf(stderr, "fuse: memory allocation failed\n");
4788  return -1;
4789  }
4790  t->use = 0;
4791  t->split = 0;
4792 
4793  return 0;
4794 }
4795 
4796 static void *fuse_prune_nodes(void *fuse)
4797 {
4798  struct fuse *f = fuse;
4799  int sleep_time;
4800 
4801  while(1) {
4802  sleep_time = fuse_clean_cache(f);
4803  sleep(sleep_time);
4804  }
4805  return NULL;
4806 }
4807 
4808 int fuse_start_cleanup_thread(struct fuse *f)
4809 {
4810  if (lru_enabled(f))
4811  return fuse_start_thread(&f->prune_thread, fuse_prune_nodes, f);
4812 
4813  return 0;
4814 }
4815 
4816 void fuse_stop_cleanup_thread(struct fuse *f)
4817 {
4818  if (lru_enabled(f)) {
4819  pthread_mutex_lock(&f->lock);
4820  pthread_cancel(f->prune_thread);
4821  pthread_mutex_unlock(&f->lock);
4822  pthread_join(f->prune_thread, NULL);
4823  }
4824 }
4825 
4826 
4827 FUSE_SYMVER(".symver fuse_new_31,fuse_new@@FUSE_3.1");
4828 struct fuse *fuse_new_31(struct fuse_args *args,
4829  const struct fuse_operations *op,
4830  size_t op_size, void *user_data)
4831 {
4832  struct fuse *f;
4833  struct node *root;
4834  struct fuse_fs *fs;
4835  struct fuse_lowlevel_ops llop = fuse_path_ops;
4836 
4837  f = (struct fuse *) calloc(1, sizeof(struct fuse));
4838  if (f == NULL) {
4839  fprintf(stderr, "fuse: failed to allocate fuse object\n");
4840  goto out;
4841  }
4842 
4843  f->conf.entry_timeout = 1.0;
4844  f->conf.attr_timeout = 1.0;
4845  f->conf.negative_timeout = 0.0;
4846  f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
4847 
4848  /* Parse options */
4849  if (fuse_opt_parse(args, &f->conf, fuse_lib_opts,
4850  fuse_lib_opt_proc) == -1)
4851  goto out_free;
4852 
4853  pthread_mutex_lock(&fuse_context_lock);
4854  static int builtin_modules_registered = 0;
4855  /* Have the builtin modules already been registered? */
4856  if (builtin_modules_registered == 0) {
4857  /* If not, register them. */
4858  fuse_register_module("subdir", fuse_module_subdir_factory, NULL);
4859 #ifdef HAVE_ICONV
4860  fuse_register_module("iconv", fuse_module_iconv_factory, NULL);
4861 #endif
4862  builtin_modules_registered= 1;
4863  }
4864  pthread_mutex_unlock(&fuse_context_lock);
4865 
4866  if (fuse_create_context_key() == -1)
4867  goto out_free;
4868 
4869  fs = fuse_fs_new(op, op_size, user_data);
4870  if (!fs)
4871  goto out_delete_context_key;
4872 
4873  f->fs = fs;
4874 
4875  /* Oh f**k, this is ugly! */
4876  if (!fs->op.lock) {
4877  llop.getlk = NULL;
4878  llop.setlk = NULL;
4879  }
4880 
4881  f->pagesize = getpagesize();
4882  init_list_head(&f->partial_slabs);
4883  init_list_head(&f->full_slabs);
4884  init_list_head(&f->lru_table);
4885 
4886  if (f->conf.modules) {
4887  char *module;
4888  char *next;
4889 
4890  for (module = f->conf.modules; module; module = next) {
4891  char *p;
4892  for (p = module; *p && *p != ':'; p++);
4893  next = *p ? p + 1 : NULL;
4894  *p = '\0';
4895  if (module[0] &&
4896  fuse_push_module(f, module, args) == -1)
4897  goto out_free_fs;
4898  }
4899  }
4900 
4901  if (!f->conf.ac_attr_timeout_set)
4902  f->conf.ac_attr_timeout = f->conf.attr_timeout;
4903 
4904 #if defined(__FreeBSD__) || defined(__NetBSD__)
4905  /*
4906  * In FreeBSD, we always use these settings as inode numbers
4907  * are needed to make getcwd(3) work.
4908  */
4909  f->conf.readdir_ino = 1;
4910 #endif
4911 
4912  f->se = fuse_session_new(args, &llop, sizeof(llop), f);
4913  if (f->se == NULL)
4914  goto out_free_fs;
4915 
4916  if (f->conf.debug) {
4917  fprintf(stderr, "nullpath_ok: %i\n", f->conf.nullpath_ok);
4918  }
4919 
4920  /* Trace topmost layer by default */
4921  f->fs->debug = f->conf.debug;
4922  f->ctr = 0;
4923  f->generation = 0;
4924  if (node_table_init(&f->name_table) == -1)
4925  goto out_free_session;
4926 
4927  if (node_table_init(&f->id_table) == -1)
4928  goto out_free_name_table;
4929 
4930  fuse_mutex_init(&f->lock);
4931 
4932  root = alloc_node(f);
4933  if (root == NULL) {
4934  fprintf(stderr, "fuse: memory allocation failed\n");
4935  goto out_free_id_table;
4936  }
4937  if (lru_enabled(f)) {
4938  struct node_lru *lnode = node_lru(root);
4939  init_list_head(&lnode->lru);
4940  }
4941 
4942  strcpy(root->inline_name, "/");
4943  root->name = root->inline_name;
4944 
4945  if (f->conf.intr &&
4946  fuse_init_intr_signal(f->conf.intr_signal,
4947  &f->intr_installed) == -1)
4948  goto out_free_root;
4949 
4950  root->parent = NULL;
4951  root->nodeid = FUSE_ROOT_ID;
4952  inc_nlookup(root);
4953  hash_id(f, root);
4954 
4955  return f;
4956 
4957 out_free_root:
4958  free(root);
4959 out_free_id_table:
4960  free(f->id_table.array);
4961 out_free_name_table:
4962  free(f->name_table.array);
4963 out_free_session:
4964  fuse_session_destroy(f->se);
4965 out_free_fs:
4966  if (f->fs->m)
4967  fuse_put_module(f->fs->m);
4968  free(f->fs);
4969  free(f->conf.modules);
4970 out_delete_context_key:
4971  fuse_delete_context_key();
4972 out_free:
4973  free(f);
4974 out:
4975  return NULL;
4976 }
4977 
4978 /* Emulates 3.0-style fuse_new(), which processes --help */
4979 struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
4980  size_t op_size, void *private_data);
4981 FUSE_SYMVER(".symver fuse_new_30,fuse_new@FUSE_3.0");
4982 struct fuse *fuse_new_30(struct fuse_args *args,
4983  const struct fuse_operations *op,
4984  size_t op_size, void *user_data)
4985 {
4986  struct fuse_config conf;
4987 
4988  memset(&conf, 0, sizeof(conf));
4989 
4990  const struct fuse_opt opts[] = {
4991  FUSE_LIB_OPT("-h", show_help, 1),
4992  FUSE_LIB_OPT("--help", show_help, 1),
4993  FUSE_OPT_END
4994  };
4995 
4996  if (fuse_opt_parse(args, &conf, opts,
4997  fuse_lib_opt_proc) == -1)
4998  return NULL;
4999 
5000  if (conf.show_help) {
5001  fuse_lib_help(args);
5002  return NULL;
5003  } else
5004  return fuse_new_31(args, op, op_size, user_data);
5005 }
5006 
5007 void fuse_destroy(struct fuse *f)
5008 {
5009  size_t i;
5010 
5011  if (f->conf.intr && f->intr_installed)
5012  fuse_restore_intr_signal(f->conf.intr_signal);
5013 
5014  if (f->fs) {
5015  fuse_create_context(f);
5016 
5017  for (i = 0; i < f->id_table.size; i++) {
5018  struct node *node;
5019 
5020  for (node = f->id_table.array[i]; node != NULL;
5021  node = node->id_next) {
5022  if (node->is_hidden) {
5023  char *path;
5024  if (try_get_path(f, node->nodeid, NULL, &path, NULL, false) == 0) {
5025  fuse_fs_unlink(f->fs, path);
5026  free(path);
5027  }
5028  }
5029  }
5030  }
5031  }
5032  for (i = 0; i < f->id_table.size; i++) {
5033  struct node *node;
5034  struct node *next;
5035 
5036  for (node = f->id_table.array[i]; node != NULL; node = next) {
5037  next = node->id_next;
5038  free_node(f, node);
5039  f->id_table.use--;
5040  }
5041  }
5042  assert(list_empty(&f->partial_slabs));
5043  assert(list_empty(&f->full_slabs));
5044 
5045  while (fuse_modules) {
5046  fuse_put_module(fuse_modules);
5047  }
5048  free(f->id_table.array);
5049  free(f->name_table.array);
5050  pthread_mutex_destroy(&f->lock);
5051  fuse_session_destroy(f->se);
5052  free(f->conf.modules);
5053  free(f);
5054  fuse_delete_context_key();
5055 }
5056 
5057 int fuse_mount(struct fuse *f, const char *mountpoint) {
5058  return fuse_session_mount(fuse_get_session(f), mountpoint);
5059 }
5060 
5061 
5062 void fuse_unmount(struct fuse *f) {
5064 }
5065 
5066 int fuse_version(void)
5067 {
5068  return FUSE_VERSION;
5069 }
5070 
5071 const char *fuse_pkgversion(void)
5072 {
5073  return PACKAGE_VERSION;
5074 }
void fuse_session_destroy(struct fuse_session *se)
+
int fuse_reply_err(fuse_req_t req, int err)
+
size_t off
Definition: fuse_common.h:679
+
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
+
void fuse_session_exit(struct fuse_session *se)
+
unsigned capable
Definition: fuse_common.h:381
+
uint64_t fh
Definition: fuse_common.h:72
+
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
+ + +
unsigned int writepage
Definition: fuse_common.h:43
+
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
+
void fuse_lowlevel_help(void)
+
unsigned int direct_io
Definition: fuse_common.h:46
+ +
size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct fuse_entry_param *e, off_t off)
+
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
+
uint32_t poll_events
Definition: fuse_common.h:79
+
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
+
void fuse_stop_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4816
+
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
+
unsigned int max_idle_threads
Definition: fuse_common.h:103
+
mode_t umask
+
int fuse_loop(struct fuse *f)
Definition: fuse.c:4516
+
fuse_fill_dir_flags
Definition: fuse.h:54
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
+
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
+
struct stat attr
Definition: fuse_lowlevel.h:91
+
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
+
void * fuse_req_userdata(fuse_req_t req)
+ +
int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
+ +
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
+
unsigned int keep_cache
Definition: fuse_common.h:51
+
Definition: fuse_lowlevel.h:59
+
fuse_readdir_flags
Definition: fuse.h:42
+
#define FUSE_CAP_EXPORT_SUPPORT
Definition: fuse_common.h:144
+
fuse_ino_t ino
Definition: fuse_lowlevel.h:67
+
uint64_t lock_owner
Definition: fuse_common.h:75
+
int fuse_reply_xattr(fuse_req_t req, size_t count)
+
int fuse_session_exited(struct fuse_session *se)
+
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
+
void(* getlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock)
+
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:54
+ +
int fuse_clean_cache(struct fuse *fuse)
Definition: fuse.c:4373
+ +
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
+
void fuse_destroy(struct fuse *f)
Definition: fuse.c:5007
+
int fuse_version(void)
Definition: fuse.c:5066
+
int fuse_req_interrupted(fuse_req_t req)
+
void fuse_session_reset(struct fuse_session *se)
+
void fuse_reply_none(fuse_req_t req)
+
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
+ + + + +
size_t idx
Definition: fuse_common.h:674
+ +
size_t count
Definition: fuse_common.h:669
+ +
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98
+
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
+
#define FUSE_CAP_SPLICE_READ
Definition: fuse_common.h:177
+
void fuse_session_unmount(struct fuse_session *se)
+
#define FUSE_OPT_END
Definition: fuse_opt.h:104
+
enum fuse_buf_flags flags
Definition: fuse_common.h:633
+
struct fuse_fs *(* fuse_module_factory_t)(struct fuse_args *args, struct fuse_fs *fs[])
Definition: fuse.h:1226
+
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
+
struct fuse_session * fuse_get_session(struct fuse *f)
Definition: fuse.c:4459
+
unsigned int flush
Definition: fuse_common.h:56
+
#define FUSE_OPT_KEY_KEEP
Definition: fuse_opt.h:145
+
void * private_data
Definition: fuse.h:791
+
int fuse_invalidate_path(struct fuse *f, const char *path)
Definition: fuse.c:4586
+ +
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
Definition: fuse.c:4760
+
#define FUSE_ROOT_ID
Definition: fuse_lowlevel.h:43
+
int fuse_start_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4808
+ +
#define FUSE_CAP_FLOCK_LOCKS
Definition: fuse_common.h:190
+
void fuse_lib_help(struct fuse_args *args)
Definition: fuse.c:4650
+
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
+
int fuse_interrupted(void)
Definition: fuse.c:4576
+
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:82
+
int show_help
Definition: fuse.h:271
+
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
+
uint64_t generation
Definition: fuse_lowlevel.h:82
+
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
+
int fuse_reply_write(fuse_req_t req, size_t count)
+
void * mem
Definition: fuse_common.h:640
+
int fuse_getgroups(int size, gid_t list[])
Definition: fuse.c:4567
+ +
int fuse_mount(struct fuse *f, const char *mountpoint)
Definition: fuse.c:5057
+
#define FUSE_CAP_POSIX_LOCKS
Definition: fuse_common.h:128
+
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
+
void(* setlk)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep)
+ + +
struct fuse_buf buf[1]
Definition: fuse_common.h:684
+ + + +
unsigned want
Definition: fuse_common.h:389
+
void fuse_unmount(struct fuse *f)
Definition: fuse.c:5062
+ +
int fuse_loop_mt_31(struct fuse *f, int clone_fd)
Definition: fuse.c:4544
+
const char * fuse_pkgversion(void)
Definition: fuse.c:5071
+
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
+
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
Definition: buffer.c:22
+
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
Definition: buffer.c:281
+
size_t size
Definition: fuse_common.h:628
+
struct fuse_context * fuse_get_context(void)
Definition: fuse.c:4557
+
double entry_timeout
+
double attr_timeout
Definition: fuse_lowlevel.h:97
+ + +
int fuse_reply_readlink(fuse_req_t req, const char *link)
+
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
+
void(* init)(void *userdata, struct fuse_conn_info *conn)
+
int fuse_reply_poll(fuse_req_t req, unsigned revents)
+
void fuse_exit(struct fuse *f)
Definition: fuse.c:4552
+
+ + + + diff --git a/doc/html/fuse_8h.html b/doc/html/fuse_8h.html new file mode 100644 index 0000000..27e3dc3 --- /dev/null +++ b/doc/html/fuse_8h.html @@ -0,0 +1,1004 @@ + + + + + + + +libfuse: include/fuse.h File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+ +
+
fuse.h File Reference
+
+
+
#include "fuse_common.h"
+#include <fcntl.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/uio.h>
+
+

Go to the source code of this file.

+ + + + + + + + +

+Data Structures

struct  fuse_config
 
struct  fuse_operations
 
struct  fuse_context
 
+ + + + + +

+Macros

#define fuse_main(argc, argv, op, private_data)   fuse_main_real(argc, argv, op, sizeof(*(op)), private_data)
 
#define FUSE_REGISTER_MODULE(name_, factory_)   fuse_module_factory_t fuse_module_ ## name_ ## _factory = factory_
 
+ + + + + +

+Typedefs

typedef int(* fuse_fill_dir_t) (void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
 
typedef struct fuse_fs *(* fuse_module_factory_t) (struct fuse_args *args, struct fuse_fs *fs[])
 
+ + + + + +

+Enumerations

enum  fuse_readdir_flags { FUSE_READDIR_PLUS = (1 << 0) + }
 
enum  fuse_fill_dir_flags { FUSE_FILL_DIR_PLUS = (1 << 1) + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

void fuse_lib_help (struct fuse_args *args)
 
struct fuse * fuse_new (struct fuse_args *args, const struct fuse_operations *op, size_t op_size, void *private_data)
 
int fuse_mount (struct fuse *f, const char *mountpoint)
 
void fuse_unmount (struct fuse *f)
 
void fuse_destroy (struct fuse *f)
 
int fuse_loop (struct fuse *f)
 
void fuse_exit (struct fuse *f)
 
int fuse_loop_mt_31 (struct fuse *f, int clone_fd)
 
struct fuse_contextfuse_get_context (void)
 
int fuse_getgroups (int size, gid_t list[])
 
int fuse_interrupted (void)
 
int fuse_invalidate_path (struct fuse *f, const char *path)
 
int fuse_main_real (int argc, char *argv[], const struct fuse_operations *op, size_t op_size, void *private_data)
 
int fuse_start_cleanup_thread (struct fuse *fuse)
 
void fuse_stop_cleanup_thread (struct fuse *fuse)
 
int fuse_clean_cache (struct fuse *fuse)
 
struct fuse_fs * fuse_fs_new (const struct fuse_operations *op, size_t op_size, void *private_data)
 
struct fuse_session * fuse_get_session (struct fuse *f)
 
int fuse_open_channel (const char *mountpoint, const char *options)
 
+

Detailed Description

+

This file defines the library interface of FUSE

+

IMPORTANT: you should define FUSE_USE_VERSION before including this header.

+ +

Definition in file fuse.h.

+

Macro Definition Documentation

+ +

◆ fuse_main

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#define fuse_main( argc,
 argv,
 op,
 private_data 
)   fuse_main_real(argc, argv, op, sizeof(*(op)), private_data)
+
+

Main function of FUSE.

+

This is for the lazy. This is all that has to be called from the main() function.

+

This function does the following:

    +
  • parses command line options, and handles –help and –version
  • +
  • installs signal handlers for INT, HUP, TERM and PIPE
  • +
  • registers an exit handler to unmount the filesystem on program exit
  • +
  • creates a fuse handle
  • +
  • registers the operations
  • +
  • calls either the single-threaded or the multi-threaded event loop
  • +
+

Most file systems will have to parse some file-system specific arguments before calling this function. It is recommended to do this with fuse_opt_parse() and a processing function that passes through any unknown options (this can also be achieved by just passing NULL as the processing function). That way, the remaining options can be passed directly to fuse_main().

+

fuse_main() accepts all options that can be passed to fuse_parse_cmdline(), fuse_new(), or fuse_session_new().

+

Option parsing skips argv[0], which is assumed to contain the program name. This element must always be present and is used to construct a basic usage: message for the –help output. argv[0] may also be set to the empty string. In this case the usage message is suppressed. This can be used by file systems to print their own usage line first. See hello.c for an example of how to do this.

+

Note: this is currently implemented as a macro.

+

The following error codes may be returned from fuse_main(): 1: Invalid option arguments 2: No mount point specified 3: FUSE setup failed 4: Mounting failed 5: Failed to daemonize (detach from session) 6: Failed to set up signal handlers 7: An error occured during the life of the file system

+
Parameters
+ + + + + +
argcthe argument counter passed to the main() function
argvthe argument vector passed to the main() function
opthe file system operation
private_dataInitial value for the private_data field of struct fuse_context. May be overridden by the struct fuse_operations.init handler.
+
+
+
Returns
0 on success, nonzero on failure
+

Example usage, see hello.c

+ +

Definition at line 855 of file fuse.h.

+ +
+
+ +

◆ FUSE_REGISTER_MODULE

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define FUSE_REGISTER_MODULE( name_,
 factory_ 
)   fuse_module_factory_t fuse_module_ ## name_ ## _factory = factory_
+
+

Register filesystem module

+

If the "-omodules=*name*_:..." option is present, filesystem objects are created and pushed onto the stack with the factory_ function.

+
Parameters
+ + + +
name_the name of this filesystem module
factory_the factory function for this filesystem module
+
+
+ +

Definition at line 1238 of file fuse.h.

+ +
+
+

Typedef Documentation

+ +

◆ fuse_fill_dir_t

+ +
+
+ + + + +
typedef int(* fuse_fill_dir_t) (void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
+
+

Function to add an entry in a readdir() operation

+

The off parameter can be any non-zero value that enableds the filesystem to identify the current point in the directory stream. It does not need to be the actual physical position. A value of zero is reserved to indicate that seeking in directories is not supported.

+
Parameters
+ + + + + + +
bufthe buffer passed to the readdir() operation
namethe file name of the directory entry
statfile attributes, can be NULL
offoffset of the next entry or zero
flagsfill flags
+
+
+
Returns
1 if buffer is full, zero otherwise
+ +

Definition at line 82 of file fuse.h.

+ +
+
+ +

◆ fuse_module_factory_t

+ +
+
+ + + + +
typedef struct fuse_fs*(* fuse_module_factory_t) (struct fuse_args *args, struct fuse_fs *fs[])
+
+

Factory for creating filesystem objects

+

The function may use and remove options from 'args' that belong to this module.

+

For now the 'fs' vector always contains exactly one filesystem. This is the filesystem which will be below the newly created filesystem in the stack.

+
Parameters
+ + + +
argsthe command line arguments
fsNULL terminated filesystem object vector
+
+
+
Returns
the new filesystem object
+ +

Definition at line 1226 of file fuse.h.

+ +
+
+

Enumeration Type Documentation

+ +

◆ fuse_fill_dir_flags

+ +
+
+ + + + +
enum fuse_fill_dir_flags
+
+ + +
Enumerator
FUSE_FILL_DIR_PLUS 

"Plus" mode: all file attributes are valid

+

The attributes are used by the kernel to prefill the inode cache during a readdir.

+

It is okay to set FUSE_FILL_DIR_PLUS if FUSE_READDIR_PLUS is not set and vice versa.

+
+ +

Definition at line 54 of file fuse.h.

+ +
+
+ +

◆ fuse_readdir_flags

+ +
+
+ + + + +
enum fuse_readdir_flags
+
+

Readdir flags, passed to ->readdir()

+ + +
Enumerator
FUSE_READDIR_PLUS 

"Plus" mode.

+

The kernel wants to prefill the inode cache during readdir. The filesystem may honour this by filling in the attributes and setting FUSE_FILL_DIR_FLAGS for the filler function. The filesystem may also just ignore this flag completely.

+
+ +

Definition at line 42 of file fuse.h.

+ +
+
+

Function Documentation

+ +

◆ fuse_clean_cache()

+ +
+
+ + + + + + + + +
int fuse_clean_cache (struct fuse * fuse)
+
+

Iterate over cache removing stale entries use in conjunction with "-oremember"

+

NOTE: This is already done for the standard sessions

+
Parameters
+ + +
fusestruct fuse pointer for fuse instance
+
+
+
Returns
the number of seconds until the next cleanup
+ +

Definition at line 4373 of file fuse.c.

+ +
+
+ +

◆ fuse_destroy()

+ +
+
+ + + + + + + + +
void fuse_destroy (struct fuse * f)
+
+

Destroy the FUSE handle.

+

NOTE: This function does not unmount the filesystem. If this is needed, call fuse_unmount() before calling this function.

+
Parameters
+ + +
fthe FUSE handle
+
+
+ +

Definition at line 5007 of file fuse.c.

+ +
+
+ +

◆ fuse_exit()

+ +
+
+ + + + + + + + +
void fuse_exit (struct fuse * f)
+
+

Flag session as terminated

+

This function will cause any running event loops to exit on the next opportunity.

+
Parameters
+ + +
fthe FUSE handle
+
+
+ +

Definition at line 4552 of file fuse.c.

+ +
+
+ +

◆ fuse_fs_new()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
struct fuse_fs* fuse_fs_new (const struct fuse_operationsop,
size_t op_size,
void * private_data 
)
+
+

Create a new fuse filesystem object

+

This is usually called from the factory of a fuse module to create a new instance of a filesystem.

+
Parameters
+ + + + +
opthe filesystem operations
op_sizethe size of the fuse_operations structure
private_dataInitial value for the private_data field of struct fuse_context. May be overridden by the struct fuse_operations.init handler.
+
+
+
Returns
a new filesystem object
+ +

Definition at line 4760 of file fuse.c.

+ +
+
+ +

◆ fuse_get_context()

+ +
+
+ + + + + + + + +
struct fuse_context* fuse_get_context (void )
+
+

Get the current context

+

The context is only valid for the duration of a filesystem operation, and thus must not be stored and used later.

+
Returns
the context
+ +

Definition at line 4557 of file fuse.c.

+ +
+
+ +

◆ fuse_get_session()

+ +
+
+ + + + + + + + +
struct fuse_session* fuse_get_session (struct fuse * f)
+
+

Get session from fuse object

+ +

Definition at line 4459 of file fuse.c.

+ +
+
+ +

◆ fuse_getgroups()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_getgroups (int size,
gid_t list[] 
)
+
+

Get the current supplementary group IDs for the current request

+

Similar to the getgroups(2) system call, except the return value is always the total number of group IDs, even if it is larger than the specified size.

+

The current fuse kernel module in linux (as of 2.6.30) doesn't pass the group list to userspace, hence this function needs to parse "/proc/$TID/task/$TID/status" to get the group IDs.

+

This feature may not be supported on all operating systems. In such a case this function will return -ENOSYS.

+
Parameters
+ + + +
sizesize of given array
listarray of group IDs to be filled in
+
+
+
Returns
the total number of supplementary group IDs or -errno on failure
+ +

Definition at line 4567 of file fuse.c.

+ +
+
+ +

◆ fuse_interrupted()

+ +
+
+ + + + + + + + +
int fuse_interrupted (void )
+
+

Check if the current request has already been interrupted

+
Returns
1 if the request has been interrupted, 0 otherwise
+ +

Definition at line 4576 of file fuse.c.

+ +
+
+ +

◆ fuse_invalidate_path()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_invalidate_path (struct fuse * f,
const char * path 
)
+
+

Invalidates cache for the given path.

+

This calls fuse_lowlevel_notify_inval_inode internally.

+
Returns
0 on successful invalidation, negative error value otherwise. This routine may return -ENOENT to indicate that there was no entry to be invalidated, e.g., because the path has not been seen before or has been forgotten; this should not be considered to be an error.
+ +

Definition at line 4586 of file fuse.c.

+ +
+
+ +

◆ fuse_lib_help()

+ +
+
+ + + + + + + + +
void fuse_lib_help (struct fuse_argsargs)
+
+

Print available options (high- and low-level) to stdout. This is not an exhaustive list, but includes only those options that may be of interest to an end-user of a file system.

+

The function looks at the argument vector only to determine if there are additional modules to be loaded (module=foo option), and attempts to call their help functions as well.

+
Parameters
+ + +
argsthe argument vector.
+
+
+ +

Definition at line 4650 of file fuse.c.

+ +
+
+ +

◆ fuse_loop()

+ +
+
+ + + + + + + + +
int fuse_loop (struct fuse * f)
+
+

FUSE event loop.

+

Requests from the kernel are processed, and the appropriate operations are called.

+

For a description of the return value and the conditions when the event loop exits, refer to the documentation of fuse_session_loop().

+
Parameters
+ + +
fthe FUSE handle
+
+
+
Returns
see fuse_session_loop()
+

See also: fuse_loop_mt()

+ +

Definition at line 4516 of file fuse.c.

+ +
+
+ +

◆ fuse_loop_mt_31()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_loop_mt_31 (struct fuse * f,
int clone_fd 
)
+
+

FUSE event loop with multiple threads

+

Requests from the kernel are processed, and the appropriate operations are called. Request are processed in parallel by distributing them between multiple threads.

+

For a description of the return value and the conditions when the event loop exits, refer to the documentation of fuse_session_loop().

+

Note: using fuse_loop() instead of fuse_loop_mt() means you are running in single-threaded mode, and that you will not have to worry about reentrancy, though you will have to worry about recursive lookups. In single-threaded mode, FUSE will wait for one callback to return before calling another.

+

Enabling multiple threads, by using fuse_loop_mt(), will cause FUSE to make multiple simultaneous calls into the various callback functions given by your fuse_operations record.

+

If you are using multiple threads, you can enjoy all the parallel execution and interactive response benefits of threads, and you get to enjoy all the benefits of race conditions and locking bugs, too. Ensure that any code used in the callback function of fuse_operations is also thread-safe.

+
Parameters
+ + + +
fthe FUSE handle
configloop configuration
+
+
+
Returns
see fuse_session_loop()
+

See also: fuse_loop()

+ +

Definition at line 4544 of file fuse.c.

+ +
+
+ +

◆ fuse_main_real()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_main_real (int argc,
char * argv[],
const struct fuse_operationsop,
size_t op_size,
void * private_data 
)
+
+

The real main function

+

Do not call this directly, use fuse_main()

+ +

Definition at line 279 of file helper.c.

+ +
+
+ +

◆ fuse_mount()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_mount (struct fuse * f,
const char * mountpoint 
)
+
+

Mount a FUSE file system.

+
Parameters
+ + + +
mountpointthe mount point path
fthe FUSE handle
+
+
+
Returns
0 on success, -1 on failure.
+ +

Definition at line 5057 of file fuse.c.

+ +
+
+ +

◆ fuse_new()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
struct fuse* fuse_new (struct fuse_argsargs,
const struct fuse_operationsop,
size_t op_size,
void * private_data 
)
+
+

Create a new FUSE filesystem.

+

This function accepts most file-system independent mount options (like context, nodev, ro - see mount(8)), as well as the FUSE-specific mount options from mount.fuse(8).

+

If the –help option is specified, the function writes a help text to stdout and returns NULL.

+

Option parsing skips argv[0], which is assumed to contain the program name. This element must always be present and is used to construct a basic usage: message for the –help output. If argv[0] is set to the empty string, no usage message is included in the –help output.

+

If an unknown option is passed in, an error message is written to stderr and the function returns NULL.

+
Parameters
+ + + + + +
argsargument vector
opthe filesystem operations
op_sizethe size of the fuse_operations structure
private_dataInitial value for the private_data field of struct fuse_context. May be overridden by the struct fuse_operations.init handler.
+
+
+
Returns
the created FUSE handle
+ +
+
+ +

◆ fuse_open_channel()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_open_channel (const char * mountpoint,
const char * options 
)
+
+

Open a FUSE file descriptor and set up the mount for the given mountpoint and flags.

+
Parameters
+ + + +
mountpointreference to the mount in the file system
optionsmount options
+
+
+
Returns
the FUSE file descriptor or -1 upon error
+ +

Definition at line 424 of file helper.c.

+ +
+
+ +

◆ fuse_start_cleanup_thread()

+ +
+
+ + + + + + + + +
int fuse_start_cleanup_thread (struct fuse * fuse)
+
+

Start the cleanup thread when using option "remember".

+

This is done automatically by fuse_loop_mt()

Parameters
+ + +
fusestruct fuse pointer for fuse instance
+
+
+
Returns
0 on success and -1 on error
+ +

Definition at line 4808 of file fuse.c.

+ +
+
+ +

◆ fuse_stop_cleanup_thread()

+ +
+
+ + + + + + + + +
void fuse_stop_cleanup_thread (struct fuse * fuse)
+
+

Stop the cleanup thread when using option "remember".

+

This is done automatically by fuse_loop_mt()

Parameters
+ + +
fusestruct fuse pointer for fuse instance
+
+
+ +

Definition at line 4816 of file fuse.c.

+ +
+
+ +

◆ fuse_unmount()

+ +
+
+ + + + + + + + +
void fuse_unmount (struct fuse * f)
+
+

Unmount a FUSE file system.

+

See fuse_session_unmount() for additional information.

+
Parameters
+ + +
fthe FUSE handle
+
+
+ +

Definition at line 5062 of file fuse.c.

+ +
+
+
+ + + + diff --git a/doc/html/fuse_8h_source.html b/doc/html/fuse_8h_source.html new file mode 100644 index 0000000..ede7cdb --- /dev/null +++ b/doc/html/fuse_8h_source.html @@ -0,0 +1,116 @@ + + + + + + + +libfuse: include/fuse.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse.h
+
+
+Go to the documentation of this file.
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU LGPLv2.
6  See the file COPYING.LIB.
7 */
8 
9 #ifndef FUSE_H_
10 #define FUSE_H_
11 
19 #include "fuse_common.h"
20 
21 #include <fcntl.h>
22 #include <time.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <sys/statvfs.h>
26 #include <sys/uio.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /* ----------------------------------------------------------- *
33  * Basic FUSE API *
34  * ----------------------------------------------------------- */
35 
37 struct fuse;
38 
51  FUSE_READDIR_PLUS = (1 << 0),
52 };
53 
64  FUSE_FILL_DIR_PLUS = (1 << 1),
65 };
66 
82 typedef int (*fuse_fill_dir_t) (void *buf, const char *name,
83  const struct stat *stbuf, off_t off,
84  enum fuse_fill_dir_flags flags);
93 struct fuse_config {
98  int set_gid;
99  unsigned int gid;
100 
105  int set_uid;
106  unsigned int uid;
107 
112  int set_mode;
113  unsigned int umask;
114 
120 
130 
135  double attr_timeout;
136 
140  int intr;
141 
148 
159  int remember;
160 
178 
190  int use_ino;
191 
200 
219 
238 
246 
253  double ac_attr_timeout;
254 
266 
272  char *modules;
273  int debug;
274 };
275 
276 
311  int (*getattr) (const char *, struct stat *, struct fuse_file_info *fi);
312 
321  int (*readlink) (const char *, char *, size_t);
322 
329  int (*mknod) (const char *, mode_t, dev_t);
330 
337  int (*mkdir) (const char *, mode_t);
338 
340  int (*unlink) (const char *);
341 
343  int (*rmdir) (const char *);
344 
346  int (*symlink) (const char *, const char *);
347 
357  int (*rename) (const char *, const char *, unsigned int flags);
358 
360  int (*link) (const char *, const char *);
361 
367  int (*chmod) (const char *, mode_t, struct fuse_file_info *fi);
368 
377  int (*chown) (const char *, uid_t, gid_t, struct fuse_file_info *fi);
378 
387  int (*truncate) (const char *, off_t, struct fuse_file_info *fi);
388 
437  int (*open) (const char *, struct fuse_file_info *);
438 
448  int (*read) (const char *, char *, size_t, off_t,
449  struct fuse_file_info *);
450 
460  int (*write) (const char *, const char *, size_t, off_t,
461  struct fuse_file_info *);
462 
467  int (*statfs) (const char *, struct statvfs *);
468 
490  int (*flush) (const char *, struct fuse_file_info *);
491 
504  int (*release) (const char *, struct fuse_file_info *);
505 
511  int (*fsync) (const char *, int, struct fuse_file_info *);
512 
514  int (*setxattr) (const char *, const char *, const char *, size_t, int);
515 
517  int (*getxattr) (const char *, const char *, char *, size_t);
518 
520  int (*listxattr) (const char *, char *, size_t);
521 
523  int (*removexattr) (const char *, const char *);
524 
533  int (*opendir) (const char *, struct fuse_file_info *);
534 
550  int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
551  struct fuse_file_info *, enum fuse_readdir_flags);
552 
555  int (*releasedir) (const char *, struct fuse_file_info *);
556 
562  int (*fsyncdir) (const char *, int, struct fuse_file_info *);
563 
572  void *(*init) (struct fuse_conn_info *conn,
573  struct fuse_config *cfg);
574 
580  void (*destroy) (void *private_data);
581 
591  int (*access) (const char *, int);
592 
603  int (*create) (const char *, mode_t, struct fuse_file_info *);
604 
635  int (*lock) (const char *, struct fuse_file_info *, int cmd,
636  struct flock *);
637 
650  int (*utimens) (const char *, const struct timespec tv[2],
651  struct fuse_file_info *fi);
652 
659  int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
660 
674  int (*ioctl) (const char *, int cmd, void *arg,
675  struct fuse_file_info *, unsigned int flags, void *data);
676 
692  int (*poll) (const char *, struct fuse_file_info *,
693  struct fuse_pollhandle *ph, unsigned *reventsp);
694 
704  int (*write_buf) (const char *, struct fuse_bufvec *buf, off_t off,
705  struct fuse_file_info *);
706 
721  int (*read_buf) (const char *, struct fuse_bufvec **bufp,
722  size_t size, off_t off, struct fuse_file_info *);
741  int (*flock) (const char *, struct fuse_file_info *, int op);
742 
751  int (*fallocate) (const char *, int, off_t, off_t,
752  struct fuse_file_info *);
753 
765  ssize_t (*copy_file_range) (const char *path_in,
766  struct fuse_file_info *fi_in,
767  off_t offset_in, const char *path_out,
768  struct fuse_file_info *fi_out,
769  off_t offset_out, size_t size, int flags);
770 };
771 
777 struct fuse_context {
779  struct fuse *fuse;
780 
782  uid_t uid;
783 
785  gid_t gid;
786 
788  pid_t pid;
789 
792 
794  mode_t umask;
795 };
796 
851 /*
852  int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
853  void *private_data);
854 */
855 #define fuse_main(argc, argv, op, private_data) \
856  fuse_main_real(argc, argv, op, sizeof(*(op)), private_data)
857 
858 /* ----------------------------------------------------------- *
859  * More detailed API *
860  * ----------------------------------------------------------- */
861 
873 void fuse_lib_help(struct fuse_args *args);
874 
902 #if FUSE_USE_VERSION == 30
903 struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
904  size_t op_size, void *private_data);
905 #define fuse_new(args, op, size, data) fuse_new_30(args, op, size, data)
906 #else
907 struct fuse *fuse_new(struct fuse_args *args, const struct fuse_operations *op,
908  size_t op_size, void *private_data);
909 #endif
910 
919 int fuse_mount(struct fuse *f, const char *mountpoint);
920 
928 void fuse_unmount(struct fuse *f);
929 
938 void fuse_destroy(struct fuse *f);
939 
955 int fuse_loop(struct fuse *f);
956 
965 void fuse_exit(struct fuse *f);
966 
998 #if FUSE_USE_VERSION < 32
999 int fuse_loop_mt_31(struct fuse *f, int clone_fd);
1000 #define fuse_loop_mt(f, clone_fd) fuse_loop_mt_31(f, clone_fd)
1001 #else
1002 int fuse_loop_mt(struct fuse *f, struct fuse_loop_config *config);
1003 #endif
1004 
1013 struct fuse_context *fuse_get_context(void);
1014 
1033 int fuse_getgroups(int size, gid_t list[]);
1034 
1040 int fuse_interrupted(void);
1041 
1053 int fuse_invalidate_path(struct fuse *f, const char *path);
1054 
1060 int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
1061  size_t op_size, void *private_data);
1062 
1070 int fuse_start_cleanup_thread(struct fuse *fuse);
1071 
1078 void fuse_stop_cleanup_thread(struct fuse *fuse);
1079 
1089 int fuse_clean_cache(struct fuse *fuse);
1090 
1091 /*
1092  * Stacking API
1093  */
1094 
1100 struct fuse_fs;
1101 
1102 /*
1103  * These functions call the relevant filesystem operation, and return
1104  * the result.
1105  *
1106  * If the operation is not defined, they return -ENOSYS, with the
1107  * exception of fuse_fs_open, fuse_fs_release, fuse_fs_opendir,
1108  * fuse_fs_releasedir and fuse_fs_statfs, which return 0.
1109  */
1110 
1111 int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf,
1112  struct fuse_file_info *fi);
1113 int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
1114  const char *newpath, unsigned int flags);
1115 int fuse_fs_unlink(struct fuse_fs *fs, const char *path);
1116 int fuse_fs_rmdir(struct fuse_fs *fs, const char *path);
1117 int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname,
1118  const char *path);
1119 int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath);
1120 int fuse_fs_release(struct fuse_fs *fs, const char *path,
1121  struct fuse_file_info *fi);
1122 int fuse_fs_open(struct fuse_fs *fs, const char *path,
1123  struct fuse_file_info *fi);
1124 int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size,
1125  off_t off, struct fuse_file_info *fi);
1126 int fuse_fs_read_buf(struct fuse_fs *fs, const char *path,
1127  struct fuse_bufvec **bufp, size_t size, off_t off,
1128  struct fuse_file_info *fi);
1129 int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf,
1130  size_t size, off_t off, struct fuse_file_info *fi);
1131 int fuse_fs_write_buf(struct fuse_fs *fs, const char *path,
1132  struct fuse_bufvec *buf, off_t off,
1133  struct fuse_file_info *fi);
1134 int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
1135  struct fuse_file_info *fi);
1136 int fuse_fs_flush(struct fuse_fs *fs, const char *path,
1137  struct fuse_file_info *fi);
1138 int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf);
1139 int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
1140  struct fuse_file_info *fi);
1141 int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
1142  fuse_fill_dir_t filler, off_t off,
1143  struct fuse_file_info *fi, enum fuse_readdir_flags flags);
1144 int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
1145  struct fuse_file_info *fi);
1146 int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
1147  struct fuse_file_info *fi);
1148 int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
1149  struct fuse_file_info *fi);
1150 int fuse_fs_lock(struct fuse_fs *fs, const char *path,
1151  struct fuse_file_info *fi, int cmd, struct flock *lock);
1152 int fuse_fs_flock(struct fuse_fs *fs, const char *path,
1153  struct fuse_file_info *fi, int op);
1154 int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode,
1155  struct fuse_file_info *fi);
1156 int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid,
1157  struct fuse_file_info *fi);
1158 int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size,
1159  struct fuse_file_info *fi);
1160 int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
1161  const struct timespec tv[2], struct fuse_file_info *fi);
1162 int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask);
1163 int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
1164  size_t len);
1165 int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
1166  dev_t rdev);
1167 int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode);
1168 int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
1169  const char *value, size_t size, int flags);
1170 int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
1171  char *value, size_t size);
1172 int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
1173  size_t size);
1174 int fuse_fs_removexattr(struct fuse_fs *fs, const char *path,
1175  const char *name);
1176 int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
1177  uint64_t *idx);
1178 int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg,
1179  struct fuse_file_info *fi, unsigned int flags, void *data);
1180 int fuse_fs_poll(struct fuse_fs *fs, const char *path,
1181  struct fuse_file_info *fi, struct fuse_pollhandle *ph,
1182  unsigned *reventsp);
1183 int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,
1184  off_t offset, off_t length, struct fuse_file_info *fi);
1185 ssize_t fuse_fs_copy_file_range(struct fuse_fs *fs, const char *path_in,
1186  struct fuse_file_info *fi_in, off_t off_in,
1187  const char *path_out,
1188  struct fuse_file_info *fi_out, off_t off_out,
1189  size_t len, int flags);
1190 void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn,
1191  struct fuse_config *cfg);
1192 void fuse_fs_destroy(struct fuse_fs *fs);
1193 
1194 int fuse_notify_poll(struct fuse_pollhandle *ph);
1195 
1209 struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
1210  void *private_data);
1211 
1226 typedef struct fuse_fs *(*fuse_module_factory_t)(struct fuse_args *args,
1227  struct fuse_fs *fs[]);
1238 #define FUSE_REGISTER_MODULE(name_, factory_) \
1239  fuse_module_factory_t fuse_module_ ## name_ ## _factory = factory_
1240 
1242 struct fuse_session *fuse_get_session(struct fuse *f);
1243 
1252 int fuse_open_channel(const char *mountpoint, const char *options);
1253 
1254 #ifdef __cplusplus
1255 }
1256 #endif
1257 
1258 #endif /* FUSE_H_ */
size_t off
Definition: fuse_common.h:679
+ + +
int auto_cache
Definition: fuse.h:245
+
void fuse_stop_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4816
+
int set_gid
Definition: fuse.h:98
+
int fuse_loop(struct fuse *f)
Definition: fuse.c:4516
+
struct fuse * fuse_new(struct fuse_args *args, const struct fuse_operations *op, size_t op_size, void *private_data)
+
fuse_fill_dir_flags
Definition: fuse.h:54
+
int readdir_ino
Definition: fuse.h:199
+
int intr
Definition: fuse.h:140
+
int set_mode
Definition: fuse.h:112
+
fuse_readdir_flags
Definition: fuse.h:42
+ +
int nullpath_ok
Definition: fuse.h:265
+
double negative_timeout
Definition: fuse.h:129
+
pid_t pid
Definition: fuse.h:788
+ +
int fuse_clean_cache(struct fuse *fuse)
Definition: fuse.c:4373
+
void fuse_destroy(struct fuse *f)
Definition: fuse.c:5007
+
int set_uid
Definition: fuse.h:105
+
int remember
Definition: fuse.h:159
+
int use_ino
Definition: fuse.h:190
+ + + + +
int fuse_open_channel(const char *mountpoint, const char *options)
Definition: helper.c:424
+
gid_t gid
Definition: fuse.h:785
+
struct fuse_session * fuse_get_session(struct fuse *f)
Definition: fuse.c:4459
+
mode_t umask
Definition: fuse.h:794
+
void * private_data
Definition: fuse.h:791
+
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, size_t op_size, void *private_data)
Definition: helper.c:279
+
int fuse_invalidate_path(struct fuse *f, const char *path)
Definition: fuse.c:4586
+ +
double attr_timeout
Definition: fuse.h:135
+
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
Definition: fuse.c:4760
+
int direct_io
Definition: fuse.h:218
+
int fuse_start_cleanup_thread(struct fuse *fuse)
Definition: fuse.c:4808
+
void fuse_lib_help(struct fuse_args *args)
Definition: fuse.c:4650
+
int fuse_interrupted(void)
Definition: fuse.c:4576
+
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:82
+
int show_help
Definition: fuse.h:271
+
int fuse_getgroups(int size, gid_t list[])
Definition: fuse.c:4567
+ +
int fuse_mount(struct fuse *f, const char *mountpoint)
Definition: fuse.c:5057
+
uid_t uid
Definition: fuse.h:782
+
struct fuse * fuse
Definition: fuse.h:779
+
struct fuse_buf buf[1]
Definition: fuse_common.h:684
+ +
int ac_attr_timeout_set
Definition: fuse.h:252
+
void fuse_unmount(struct fuse *f)
Definition: fuse.c:5062
+ +
int fuse_loop_mt_31(struct fuse *f, int clone_fd)
Definition: fuse.c:4544
+
struct fuse_context * fuse_get_context(void)
Definition: fuse.c:4557
+
double entry_timeout
Definition: fuse.h:119
+
int kernel_cache
Definition: fuse.h:237
+
int intr_signal
Definition: fuse.h:147
+
int hard_remove
Definition: fuse.h:177
+
void fuse_exit(struct fuse *f)
Definition: fuse.c:4552
+
+ + + + diff --git a/doc/html/fuse__common_8h.html b/doc/html/fuse__common_8h.html new file mode 100644 index 0000000..94f1f4c --- /dev/null +++ b/doc/html/fuse__common_8h.html @@ -0,0 +1,928 @@ + + + + + + + +libfuse: include/fuse_common.h File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+ +
+
fuse_common.h File Reference
+
+
+
#include "fuse_opt.h"
+#include <stdint.h>
+#include <sys/types.h>
+
+

Go to the source code of this file.

+ + + + + + + + + + + + +

+Data Structures

struct  fuse_file_info
 
struct  fuse_loop_config
 
struct  fuse_conn_info
 
struct  fuse_buf
 
struct  fuse_bufvec
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define FUSE_MAJOR_VERSION   3
 
#define FUSE_MINOR_VERSION   2
 
#define FUSE_CAP_ASYNC_READ   (1 << 0)
 
#define FUSE_CAP_POSIX_LOCKS   (1 << 1)
 
#define FUSE_CAP_ATOMIC_O_TRUNC   (1 << 3)
 
#define FUSE_CAP_EXPORT_SUPPORT   (1 << 4)
 
#define FUSE_CAP_DONT_MASK   (1 << 6)
 
#define FUSE_CAP_SPLICE_WRITE   (1 << 7)
 
#define FUSE_CAP_SPLICE_MOVE   (1 << 8)
 
#define FUSE_CAP_SPLICE_READ   (1 << 9)
 
#define FUSE_CAP_FLOCK_LOCKS   (1 << 10)
 
#define FUSE_CAP_IOCTL_DIR   (1 << 11)
 
#define FUSE_CAP_AUTO_INVAL_DATA   (1 << 12)
 
#define FUSE_CAP_READDIRPLUS   (1 << 13)
 
#define FUSE_CAP_READDIRPLUS_AUTO   (1 << 14)
 
#define FUSE_CAP_ASYNC_DIO   (1 << 15)
 
#define FUSE_CAP_WRITEBACK_CACHE   (1 << 16)
 
#define FUSE_CAP_NO_OPEN_SUPPORT   (1 << 17)
 
#define FUSE_CAP_PARALLEL_DIROPS   (1 << 18)
 
#define FUSE_CAP_POSIX_ACL   (1 << 19)
 
#define FUSE_CAP_HANDLE_KILLPRIV   (1 << 20)
 
#define FUSE_IOCTL_COMPAT   (1 << 0)
 
+ + + + + +

+Enumerations

enum  fuse_buf_flags { FUSE_BUF_IS_FD = (1 << 1), +FUSE_BUF_FD_SEEK = (1 << 2), +FUSE_BUF_FD_RETRY = (1 << 3) + }
 
enum  fuse_buf_copy_flags { FUSE_BUF_NO_SPLICE = (1 << 1), +FUSE_BUF_FORCE_SPLICE = (1 << 2), +FUSE_BUF_SPLICE_MOVE = (1 << 3), +FUSE_BUF_SPLICE_NONBLOCK = (1 << 4) + }
 
+ + + + + + + + + + + + + + + + + + + + + +

+Functions

struct fuse_conn_info_opts * fuse_parse_conn_info_opts (struct fuse_args *args)
 
void fuse_apply_conn_info_opts (struct fuse_conn_info_opts *opts, struct fuse_conn_info *conn)
 
int fuse_daemonize (int foreground)
 
int fuse_version (void)
 
const char * fuse_pkgversion (void)
 
void fuse_pollhandle_destroy (struct fuse_pollhandle *ph)
 
size_t fuse_buf_size (const struct fuse_bufvec *bufv)
 
ssize_t fuse_buf_copy (struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
 
int fuse_set_signal_handlers (struct fuse_session *se)
 
void fuse_remove_signal_handlers (struct fuse_session *se)
 
+

Macro Definition Documentation

+ +

◆ FUSE_CAP_ASYNC_DIO

+ +
+
+ + + + +
#define FUSE_CAP_ASYNC_DIO   (1 << 15)
+
+

Indicates that the filesystem supports asynchronous direct I/O submission.

+

If this capability is not requested/available, the kernel will ensure that there is at most one pending read and one pending write request per direct I/O file-handle at any time.

+

This feature is enabled by default when supported by the kernel.

+ +

Definition at line 257 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_ASYNC_READ

+ +
+
+ + + + +
#define FUSE_CAP_ASYNC_READ   (1 << 0)
+
+

Indicates that the filesystem supports asynchronous read requests.

+

If this capability is not requested/available, the kernel will ensure that there is at most one pending read request per file-handle at any time, and will attempt to order read requests by increasing offset.

+

This feature is enabled by default when supported by the kernel.

+ +

Definition at line 120 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_ATOMIC_O_TRUNC

+ +
+
+ + + + +
#define FUSE_CAP_ATOMIC_O_TRUNC   (1 << 3)
+
+

Indicates that the filesystem supports the O_TRUNC open flag. If disabled, and an application specifies O_TRUNC, fuse first calls truncate() and then open() with O_TRUNC filtered out.

+

This feature is enabled by default when supported by the kernel.

+ +

Definition at line 137 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_AUTO_INVAL_DATA

+ +
+
+ + + + +
#define FUSE_CAP_AUTO_INVAL_DATA   (1 << 12)
+
+

Traditionally, while a file is open the FUSE kernel module only asks the filesystem for an update of the file's attributes when a client attempts to read beyond EOF. This is unsuitable for e.g. network filesystems, where the file contents may change without the kernel knowing about it.

+

If this flag is set, FUSE will check the validity of the attributes on every read. If the attributes are no longer valid (i.e., if the attr_timeout passed to fuse_reply_attr() or set in struct fuse_entry_param has passed), it will first issue a getattr request. If the new mtime differs from the previous value, any cached file contents will be invalidated as well.

+

This flag should always be set when available. If all file changes go through the kernel, attr_timeout should be set to a very large number to avoid unnecessary getattr() calls.

+

This feature is enabled by default when supported by the kernel.

+ +

Definition at line 219 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_DONT_MASK

+ +
+
+ + + + +
#define FUSE_CAP_DONT_MASK   (1 << 6)
+
+

Indicates that the kernel should not apply the umask to the file mode on create operations.

+

This feature is disabled by default.

+ +

Definition at line 152 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_EXPORT_SUPPORT

+ +
+
+ + + + +
#define FUSE_CAP_EXPORT_SUPPORT   (1 << 4)
+
+

Indicates that the filesystem supports lookups of "." and "..".

+

This feature is disabled by default.

+ +

Definition at line 144 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_FLOCK_LOCKS

+ +
+
+ + + + +
#define FUSE_CAP_FLOCK_LOCKS   (1 << 10)
+
+

If set, the calls to flock(2) will be emulated using POSIX locks and must then be handled by the filesystem's setlock() handler.

+

If not set, flock(2) calls will be handled by the FUSE kernel module internally (so any access that does not go through the kernel cannot be taken into account).

+

This feature is enabled by default when supported by the kernel and if the filesystem implements a flock() handler.

+ +

Definition at line 190 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_HANDLE_KILLPRIV

+ +
+
+ + + + +
#define FUSE_CAP_HANDLE_KILLPRIV   (1 << 20)
+
+

Indicates that the filesystem is responsible for unsetting setuid and setgid bits when a file is written, truncated, or its owner is changed.

+

This feature is enabled by default when supported by the kernel.

+ +

Definition at line 317 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_IOCTL_DIR

+ +
+
+ + + + +
#define FUSE_CAP_IOCTL_DIR   (1 << 11)
+
+

Indicates that the filesystem supports ioctl's on directories.

+

This feature is enabled by default when supported by the kernel.

+ +

Definition at line 197 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_NO_OPEN_SUPPORT

+ +
+
+ + + + +
#define FUSE_CAP_NO_OPEN_SUPPORT   (1 << 17)
+
+

Indicates support for zero-message opens. If this flag is set in the capable field of the fuse_conn_info structure, then the filesystem may return ENOSYS from the open() handler to indicate success. Further attempts to open files will be handled in the kernel. (If this flag is not set, returning ENOSYS will be treated as an error and signaled to the caller).

+

Setting (or unsetting) this flag in the want field has no effect.

+ +

Definition at line 279 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_PARALLEL_DIROPS

+ +
+
+ + + + +
#define FUSE_CAP_PARALLEL_DIROPS   (1 << 18)
+
+

Indicates support for parallel directory operations. If this flag is unset, the FUSE kernel module will ensure that lookup() and readdir() requests are never issued concurrently for the same directory.

+

This feature is enabled by default when supported by the kernel.

+ +

Definition at line 289 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_POSIX_ACL

+ +
+
+ + + + +
#define FUSE_CAP_POSIX_ACL   (1 << 19)
+
+

Indicates support for POSIX ACLs.

+

If this feature is enabled, the kernel will cache and have responsibility for enforcing ACLs. ACL will be stored as xattrs and passed to userspace, which is responsible for updating the ACLs in the filesystem, keeping the file mode in sync with the ACL, and ensuring inheritance of default ACLs when new filesystem nodes are created. Note that this requires that the file system is able to parse and interpret the xattr representation of ACLs.

+

Enabling this feature implicitly turns on the default_permissions mount option (even if it was not passed to mount(2)).

+

This feature is disabled by default.

+ +

Definition at line 308 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_POSIX_LOCKS

+ +
+
+ + + + +
#define FUSE_CAP_POSIX_LOCKS   (1 << 1)
+
+

Indicates that the filesystem supports "remote" locking.

+

This feature is enabled by default when supported by the kernel, and if getlk() and setlk() handlers are implemented.

+ +

Definition at line 128 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_READDIRPLUS

+ +
+
+ + + + +
#define FUSE_CAP_READDIRPLUS   (1 << 13)
+
+

Indicates that the filesystem supports readdirplus.

+

This feature is enabled by default when supported by the kernel and if the filesystem implements a readdirplus() handler.

+ +

Definition at line 227 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_READDIRPLUS_AUTO

+ +
+
+ + + + +
#define FUSE_CAP_READDIRPLUS_AUTO   (1 << 14)
+
+

Indicates that the filesystem supports adaptive readdirplus.

+

If FUSE_CAP_READDIRPLUS is not set, this flag has no effect.

+

If FUSE_CAP_READDIRPLUS is set and this flag is not set, the kernel will always issue readdirplus() requests to retrieve directory contents.

+

If FUSE_CAP_READDIRPLUS is set and this flag is set, the kernel will issue both readdir() and readdirplus() requests, depending on how much information is expected to be required.

+

This feature is enabled by default when supported by the kernel and if the filesystem implements both a readdirplus() and a readdir() handler.

+ +

Definition at line 246 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_SPLICE_MOVE

+ +
+
+ + + + +
#define FUSE_CAP_SPLICE_MOVE   (1 << 8)
+
+

Indicates that libfuse should try to move pages instead of copying when writing to / reading from the fuse device. This may improve performance.

+

This feature is disabled by default.

+ +

Definition at line 168 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_SPLICE_READ

+ +
+
+ + + + +
#define FUSE_CAP_SPLICE_READ   (1 << 9)
+
+

Indicates that libfuse should try to use splice() when reading from the fuse device. This may improve performance.

+

This feature is enabled by default when supported by the kernel and if the filesystem implements a write_buf() handler.

+ +

Definition at line 177 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_SPLICE_WRITE

+ +
+
+ + + + +
#define FUSE_CAP_SPLICE_WRITE   (1 << 7)
+
+

Indicates that libfuse should try to use splice() when writing to the fuse device. This may improve performance.

+

This feature is disabled by default.

+ +

Definition at line 160 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_CAP_WRITEBACK_CACHE

+ +
+
+ + + + +
#define FUSE_CAP_WRITEBACK_CACHE   (1 << 16)
+
+

Indicates that writeback caching should be enabled. This means that individual write request may be buffered and merged in the kernel before they are send to the filesystem.

+

This feature is disabled by default.

+ +

Definition at line 266 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_IOCTL_COMPAT

+ +
+
+ + + + +
#define FUSE_IOCTL_COMPAT   (1 << 0)
+
+

Ioctl flags

+

FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed FUSE_IOCTL_RETRY: retry with new iovecs FUSE_IOCTL_DIR: is a directory

+

FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs

+ +

Definition at line 329 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_MAJOR_VERSION

+ +
+
+ + + + +
#define FUSE_MAJOR_VERSION   3
+
+

Major version of FUSE library interface

+ +

Definition at line 22 of file fuse_common.h.

+ +
+
+ +

◆ FUSE_MINOR_VERSION

+ +
+
+ + + + +
#define FUSE_MINOR_VERSION   2
+
+

Minor version of FUSE library interface

+ +

Definition at line 25 of file fuse_common.h.

+ +
+
+

Enumeration Type Documentation

+ +

◆ fuse_buf_copy_flags

+ +
+
+ + + + +
enum fuse_buf_copy_flags
+
+

Buffer copy flags

+ + + + + +
Enumerator
FUSE_BUF_NO_SPLICE 

Don't use splice(2)

+

Always fall back to using read and write instead of splice(2) to copy data from one file descriptor to another.

+

If this flag is not set, then only fall back if splice is unavailable.

+
FUSE_BUF_FORCE_SPLICE 

Force splice

+

Always use splice(2) to copy data from one file descriptor to another. If splice is not available, return -EINVAL.

+
FUSE_BUF_SPLICE_MOVE 

Try to move data with splice.

+

If splice is used, try to move pages from the source to the destination instead of copying. See documentation of SPLICE_F_MOVE in splice(2) man page.

+
FUSE_BUF_SPLICE_NONBLOCK 

Don't block on the pipe when copying data with splice

+

Makes the operations on the pipe non-blocking (if the pipe is full or empty). See SPLICE_F_NONBLOCK in the splice(2) man page.

+
+ +

Definition at line 579 of file fuse_common.h.

+ +
+
+ +

◆ fuse_buf_flags

+ +
+
+ + + + +
enum fuse_buf_flags
+
+

Buffer flags

+ + + + +
Enumerator
FUSE_BUF_IS_FD 

Buffer contains a file descriptor

+

If this flag is set, the .fd field is valid, otherwise the .mem fields is valid.

+
FUSE_BUF_FD_SEEK 

Seek on the file descriptor

+

If this flag is set then the .pos field is valid and is used to seek to the given offset before performing operation on file descriptor.

+
FUSE_BUF_FD_RETRY 

Retry operation on file descriptor

+

If this flag is set then retry operation on file descriptor until .size bytes have been copied or an error or EOF is detected.

+
+ +

Definition at line 548 of file fuse_common.h.

+ +
+
+

Function Documentation

+ +

◆ fuse_apply_conn_info_opts()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void fuse_apply_conn_info_opts (struct fuse_conn_info_opts * opts,
struct fuse_conn_infoconn 
)
+
+

This function applies the (parsed) parameters in opts to the conn pointer. It may modify the following fields: wants, max_write, max_readahead, congestion_threshold, max_background, time_gran. A field is only set (or unset) if the corresponding option has been explicitly set.

+ +

Definition at line 361 of file helper.c.

+ +
+
+ +

◆ fuse_buf_copy()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
ssize_t fuse_buf_copy (struct fuse_bufvecdst,
struct fuse_bufvecsrc,
enum fuse_buf_copy_flags flags 
)
+
+

Copy data from one buffer vector to another

+
Parameters
+ + + + +
dstdestination buffer vector
srcsource buffer vector
flagsflags controlling the copy
+
+
+
Returns
actual number of bytes copied or -errno on error
+ +

Definition at line 281 of file buffer.c.

+ +
+
+ +

◆ fuse_buf_size()

+ +
+
+ + + + + + + + +
size_t fuse_buf_size (const struct fuse_bufvecbufv)
+
+

Get total size of data in a fuse buffer vector

+
Parameters
+ + +
bufvbuffer vector
+
+
+
Returns
size of data
+ +

Definition at line 22 of file buffer.c.

+ +
+
+ +

◆ fuse_daemonize()

+ +
+
+ + + + + + + + +
int fuse_daemonize (int foreground)
+
+

Go into the background

+
Parameters
+ + +
foregroundif true, stay in the foreground
+
+
+
Returns
0 on success, -1 on failure
+ +

Definition at line 225 of file helper.c.

+ +
+
+ +

◆ fuse_parse_conn_info_opts()

+ +
+
+ + + + + + + + +
struct fuse_conn_info_opts* fuse_parse_conn_info_opts (struct fuse_argsargs)
+
+

This function parses several command-line options that can be used to override elements of struct fuse_conn_info. The pointer returned by this function should be passed to the fuse_apply_conn_info_opts() method by the file system's init() handler.

+

Before using this function, think twice if you really want these parameters to be adjustable from the command line. In most cases, they should be determined by the file system internally.

+

The following options are recognized:

+

-o max_write=N sets conn->max_write -o max_readahead=N sets conn->max_readahead -o max_background=N sets conn->max_background -o congestion_threshold=N sets conn->congestion_threshold -o async_read sets FUSE_CAP_ASYNC_READ in conn->want -o sync_read unsets FUSE_CAP_ASYNC_READ in conn->want -o atomic_o_trunc sets FUSE_CAP_ATOMIC_O_TRUNC in conn->want -o no_remote_lock Equivalent to -o no_remote_flock,no_remote_posix_lock -o no_remote_flock Unsets FUSE_CAP_FLOCK_LOCKS in conn->want -o no_remote_posix_lock Unsets FUSE_CAP_POSIX_LOCKS in conn->want -o [no_]splice_write (un-)sets FUSE_CAP_SPLICE_WRITE in conn->want -o [no_]splice_move (un-)sets FUSE_CAP_SPLICE_MOVE in conn->want -o [no_]splice_read (un-)sets FUSE_CAP_SPLICE_READ in conn->want -o [no_]auto_inval_data (un-)sets FUSE_CAP_AUTO_INVAL_DATA in conn->want -o readdirplus=no unsets FUSE_CAP_READDIRPLUS in conn->want -o readdirplus=yes sets FUSE_CAP_READDIRPLUS and unsets FUSE_CAP_READDIRPLUS_AUTO in conn->want -o readdirplus=auto sets FUSE_CAP_READDIRPLUS and FUSE_CAP_READDIRPLUS_AUTO in conn->want -o [no_]async_dio (un-)sets FUSE_CAP_ASYNC_DIO in conn->want -o [no_]writeback_cache (un-)sets FUSE_CAP_WRITEBACK_CACHE in conn->want -o time_gran=N sets conn->time_gran

+

Known options will be removed from args, unknown options will be passed through unchanged.

+
Parameters
+ + +
argsargument vector (input+output)
+
+
+
Returns
parsed options
+ +

Definition at line 408 of file helper.c.

+ +
+
+ +

◆ fuse_pkgversion()

+ +
+
+ + + + + + + + +
const char* fuse_pkgversion (void )
+
+

Get the full package version string of the library

+
Returns
the package version
+ +

Definition at line 5071 of file fuse.c.

+ +
+
+ +

◆ fuse_pollhandle_destroy()

+ +
+
+ + + + + + + + +
void fuse_pollhandle_destroy (struct fuse_pollhandle * ph)
+
+

Destroy poll handle

+
Parameters
+ + +
phthe poll handle
+
+
+ +

Definition at line 1766 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_remove_signal_handlers()

+ +
+
+ + + + + + + + +
void fuse_remove_signal_handlers (struct fuse_session * se)
+
+

Restore default signal handlers

+

Resets global session. After this fuse_set_signal_handlers() may be called again.

+
Parameters
+ + +
sethe same session as given in fuse_set_signal_handlers()
+
+
+

See also: fuse_set_signal_handlers()

+ +

Definition at line 79 of file fuse_signals.c.

+ +
+
+ +

◆ fuse_set_signal_handlers()

+ +
+
+ + + + + + + + +
int fuse_set_signal_handlers (struct fuse_session * se)
+
+

Exit session on HUP, TERM and INT signals and ignore PIPE signal

+

Stores session in a global variable. May only be called once per process until fuse_remove_signal_handlers() is called.

+

Once either of the POSIX signals arrives, the signal handler calls fuse_session_exit().

+
Parameters
+ + +
sethe session to exit
+
+
+
Returns
0 on success, -1 on failure
+

See also: fuse_remove_signal_handlers()

+ +

Definition at line 62 of file fuse_signals.c.

+ +
+
+ +

◆ fuse_version()

+ +
+
+ + + + + + + + +
int fuse_version (void )
+
+

Get the version of the library

+
Returns
the version
+ +

Definition at line 5066 of file fuse.c.

+ +
+
+
+ + + + diff --git a/doc/html/fuse__common_8h_source.html b/doc/html/fuse__common_8h_source.html new file mode 100644 index 0000000..031f563 --- /dev/null +++ b/doc/html/fuse__common_8h_source.html @@ -0,0 +1,111 @@ + + + + + + + +libfuse: include/fuse_common.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_common.h
+
+
+Go to the documentation of this file.
1 /* FUSE: Filesystem in Userspace
2  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
3 
4  This program can be distributed under the terms of the GNU LGPLv2.
5  See the file COPYING.LIB.
6 */
7 
10 #if !defined(FUSE_H_) && !defined(FUSE_LOWLEVEL_H_)
11 #error "Never include <fuse_common.h> directly; use <fuse.h> or <fuse_lowlevel.h> instead."
12 #endif
13 
14 #ifndef FUSE_COMMON_H_
15 #define FUSE_COMMON_H_
16 
17 #include "fuse_opt.h"
18 #include <stdint.h>
19 #include <sys/types.h>
20 
22 #define FUSE_MAJOR_VERSION 3
23 
25 #define FUSE_MINOR_VERSION 2
26 
27 #define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min))
28 #define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
39  int flags;
40 
43  unsigned int writepage : 1;
44 
46  unsigned int direct_io : 1;
47 
51  unsigned int keep_cache : 1;
52 
56  unsigned int flush : 1;
57 
60  unsigned int nonseekable : 1;
61 
62  /* Indicates that flock locks for this file should be
63  released. If set, lock_owner shall contain a valid value.
64  May only be set in ->release(). */
65  unsigned int flock_release : 1;
66 
68  unsigned int padding : 27;
69 
72  uint64_t fh;
73 
75  uint64_t lock_owner;
76 
79  uint32_t poll_events;
80 };
81 
91  int clone_fd;
92 
103  unsigned int max_idle_threads;
104 };
105 
106 /**************************************************************************
107  * Capability bits for 'fuse_conn_info.capable' and 'fuse_conn_info.want' *
108  **************************************************************************/
109 
120 #define FUSE_CAP_ASYNC_READ (1 << 0)
121 
128 #define FUSE_CAP_POSIX_LOCKS (1 << 1)
129 
137 #define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
138 
144 #define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
145 
152 #define FUSE_CAP_DONT_MASK (1 << 6)
153 
160 #define FUSE_CAP_SPLICE_WRITE (1 << 7)
161 
168 #define FUSE_CAP_SPLICE_MOVE (1 << 8)
169 
177 #define FUSE_CAP_SPLICE_READ (1 << 9)
178 
190 #define FUSE_CAP_FLOCK_LOCKS (1 << 10)
191 
197 #define FUSE_CAP_IOCTL_DIR (1 << 11)
198 
219 #define FUSE_CAP_AUTO_INVAL_DATA (1 << 12)
220 
227 #define FUSE_CAP_READDIRPLUS (1 << 13)
228 
246 #define FUSE_CAP_READDIRPLUS_AUTO (1 << 14)
247 
257 #define FUSE_CAP_ASYNC_DIO (1 << 15)
258 
266 #define FUSE_CAP_WRITEBACK_CACHE (1 << 16)
267 
279 #define FUSE_CAP_NO_OPEN_SUPPORT (1 << 17)
280 
289 #define FUSE_CAP_PARALLEL_DIROPS (1 << 18)
290 
308 #define FUSE_CAP_POSIX_ACL (1 << 19)
309 
317 #define FUSE_CAP_HANDLE_KILLPRIV (1 << 20)
318 
329 #define FUSE_IOCTL_COMPAT (1 << 0)
330 #define FUSE_IOCTL_UNRESTRICTED (1 << 1)
331 #define FUSE_IOCTL_RETRY (1 << 2)
332 #define FUSE_IOCTL_DIR (1 << 4)
333 
334 #define FUSE_IOCTL_MAX_IOV 256
335 
347  unsigned proto_major;
348 
352  unsigned proto_minor;
353 
357  unsigned max_write;
358 
371  unsigned max_read;
372 
376  unsigned max_readahead;
377 
381  unsigned capable;
382 
389  unsigned want;
390 
419  unsigned max_background;
420 
430 
446  unsigned time_gran;
447 
451  unsigned reserved[22];
452 };
453 
454 struct fuse_session;
455 struct fuse_pollhandle;
456 struct fuse_conn_info_opts;
457 
500 struct fuse_conn_info_opts* fuse_parse_conn_info_opts(struct fuse_args *args);
501 
509 void fuse_apply_conn_info_opts(struct fuse_conn_info_opts *opts,
510  struct fuse_conn_info *conn);
511 
518 int fuse_daemonize(int foreground);
519 
525 int fuse_version(void);
526 
532 const char *fuse_pkgversion(void);
533 
539 void fuse_pollhandle_destroy(struct fuse_pollhandle *ph);
540 
541 /* ----------------------------------------------------------- *
542  * Data buffer *
543  * ----------------------------------------------------------- */
544 
555  FUSE_BUF_IS_FD = (1 << 1),
556 
564  FUSE_BUF_FD_SEEK = (1 << 2),
565 
573  FUSE_BUF_FD_RETRY = (1 << 3),
574 };
575 
589  FUSE_BUF_NO_SPLICE = (1 << 1),
590 
598 
607 
616 };
617 
624 struct fuse_buf {
628  size_t size;
629 
634 
640  void *mem;
641 
647  int fd;
648 
654  off_t pos;
655 };
656 
665 struct fuse_bufvec {
669  size_t count;
670 
674  size_t idx;
675 
679  size_t off;
680 
684  struct fuse_buf buf[1];
685 };
686 
687 /* Initialize bufvec with a single buffer of given size */
688 #define FUSE_BUFVEC_INIT(size__) \
689  ((struct fuse_bufvec) { \
690  /* .count= */ 1, \
691  /* .idx = */ 0, \
692  /* .off = */ 0, \
693  /* .buf = */ { /* [0] = */ { \
694  /* .size = */ (size__), \
695  /* .flags = */ (enum fuse_buf_flags) 0, \
696  /* .mem = */ NULL, \
697  /* .fd = */ -1, \
698  /* .pos = */ 0, \
699  } } \
700  } )
701 
708 size_t fuse_buf_size(const struct fuse_bufvec *bufv);
709 
718 ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src,
720 
721 /* ----------------------------------------------------------- *
722  * Signal handling *
723  * ----------------------------------------------------------- */
724 
740 int fuse_set_signal_handlers(struct fuse_session *se);
741 
753 void fuse_remove_signal_handlers(struct fuse_session *se);
754 
755 /* ----------------------------------------------------------- *
756  * Compatibility stuff *
757  * ----------------------------------------------------------- */
758 
759 #if !defined(FUSE_USE_VERSION) || FUSE_USE_VERSION < 30
760 # error only API version 30 or greater is supported
761 #endif
762 
763 #ifdef __cplusplus
764 }
765 #endif
766 
767 
768 /*
769  * This interface uses 64 bit off_t.
770  *
771  * On 32bit systems please add -D_FILE_OFFSET_BITS=64 to your compile flags!
772  */
773 
774 #if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 6) && !defined __cplusplus
775 _Static_assert(sizeof(off_t) == 8, "fuse: off_t must be 64bit");
776 #else
777 struct _fuse_off_t_must_be_64bit_dummy_struct \
778  { unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1); };
779 #endif
780 
781 #endif /* FUSE_COMMON_H_ */
size_t off
Definition: fuse_common.h:679
+
fuse_buf_flags
Definition: fuse_common.h:548
+
unsigned capable
Definition: fuse_common.h:381
+
uint64_t fh
Definition: fuse_common.h:72
+ +
unsigned int writepage
Definition: fuse_common.h:43
+
unsigned int direct_io
Definition: fuse_common.h:46
+ +
uint32_t poll_events
Definition: fuse_common.h:79
+
int fuse_daemonize(int foreground)
Definition: helper.c:225
+
unsigned max_write
Definition: fuse_common.h:357
+ +
unsigned proto_minor
Definition: fuse_common.h:352
+
unsigned int max_idle_threads
Definition: fuse_common.h:103
+
unsigned max_background
Definition: fuse_common.h:419
+ +
unsigned int keep_cache
Definition: fuse_common.h:51
+
uint64_t lock_owner
Definition: fuse_common.h:75
+ +
int fuse_set_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:62
+
off_t pos
Definition: fuse_common.h:654
+
void fuse_remove_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:79
+ +
int fuse_version(void)
Definition: fuse.c:5066
+
struct fuse_conn_info_opts * fuse_parse_conn_info_opts(struct fuse_args *args)
Definition: helper.c:408
+ +
void fuse_apply_conn_info_opts(struct fuse_conn_info_opts *opts, struct fuse_conn_info *conn)
Definition: helper.c:361
+ + +
size_t idx
Definition: fuse_common.h:674
+
size_t count
Definition: fuse_common.h:669
+ +
unsigned int nonseekable
Definition: fuse_common.h:60
+
unsigned congestion_threshold
Definition: fuse_common.h:429
+
void fuse_pollhandle_destroy(struct fuse_pollhandle *ph)
+
unsigned int flush
Definition: fuse_common.h:56
+
unsigned max_read
Definition: fuse_common.h:371
+ +
unsigned max_readahead
Definition: fuse_common.h:376
+
unsigned proto_major
Definition: fuse_common.h:347
+
void * mem
Definition: fuse_common.h:640
+ +
unsigned want
Definition: fuse_common.h:389
+ +
const char * fuse_pkgversion(void)
Definition: fuse.c:5071
+ +
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
Definition: buffer.c:22
+
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
Definition: buffer.c:281
+
size_t size
Definition: fuse_common.h:628
+
fuse_buf_copy_flags
Definition: fuse_common.h:579
+ + +
unsigned int padding
Definition: fuse_common.h:68
+
unsigned time_gran
Definition: fuse_common.h:446
+ +
+ + + + diff --git a/doc/html/fuse__i_8h_source.html b/doc/html/fuse__i_8h_source.html new file mode 100644 index 0000000..7771c32 --- /dev/null +++ b/doc/html/fuse__i_8h_source.html @@ -0,0 +1,70 @@ + + + + + + + +libfuse: lib/fuse_i.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_i.h
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU LGPLv2.
6  See the file COPYING.LIB
7 */
8 
9 #include "fuse.h"
10 #include "fuse_lowlevel.h"
11 
12 struct mount_opts;
13 
14 struct fuse_req {
15  struct fuse_session *se;
16  uint64_t unique;
17  int ctr;
18  pthread_mutex_t lock;
19  struct fuse_ctx ctx;
20  struct fuse_chan *ch;
21  int interrupted;
22  unsigned int ioctl_64bit : 1;
23  union {
24  struct {
25  uint64_t unique;
26  } i;
27  struct {
29  void *data;
30  } ni;
31  } u;
32  struct fuse_req *next;
33  struct fuse_req *prev;
34 };
35 
36 struct fuse_notify_req {
37  uint64_t unique;
38  void (*reply)(struct fuse_notify_req *, fuse_req_t, fuse_ino_t,
39  const void *, const struct fuse_buf *);
40  struct fuse_notify_req *next;
41  struct fuse_notify_req *prev;
42 };
43 
44 struct fuse_session {
45  char *mountpoint;
46  volatile int exited;
47  int fd;
48  struct mount_opts *mo;
49  int debug;
50  int deny_others;
51  struct fuse_lowlevel_ops op;
52  int got_init;
53  struct cuse_data *cuse_data;
54  void *userdata;
55  uid_t owner;
56  struct fuse_conn_info conn;
57  struct fuse_req list;
58  struct fuse_req interrupts;
59  pthread_mutex_t lock;
60  int got_destroy;
61  pthread_key_t pipe_key;
62  int broken_splice_nonblock;
63  uint64_t notify_ctr;
64  struct fuse_notify_req notify_list;
65  size_t bufsize;
66  int error;
67 };
68 
69 struct fuse_chan {
70  pthread_mutex_t lock;
71  int ctr;
72  int fd;
73 };
74 
82 struct fuse_module {
83  char *name;
84  fuse_module_factory_t factory;
85  struct fuse_module *next;
86  struct fusemod_so *so;
87  int ctr;
88 };
89 
90 /* ----------------------------------------------------------- *
91  * Channel interface (when using -o clone_fd) *
92  * ----------------------------------------------------------- */
93 
100 struct fuse_chan *fuse_chan_get(struct fuse_chan *ch);
101 
107 void fuse_chan_put(struct fuse_chan *ch);
108 
109 struct mount_opts *parse_mount_opts(struct fuse_args *args);
110 void destroy_mount_opts(struct mount_opts *mo);
111 void fuse_mount_version(void);
112 unsigned get_max_read(struct mount_opts *o);
113 void fuse_kern_unmount(const char *mountpoint, int fd);
114 int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo);
115 
116 int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
117  int count);
118 void fuse_free_req(fuse_req_t req);
119 
120 void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeide, const void *inarg);
121 
122 int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg);
123 
124 int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf,
125  struct fuse_chan *ch);
126 void fuse_session_process_buf_int(struct fuse_session *se,
127  const struct fuse_buf *buf, struct fuse_chan *ch);
128 
129 struct fuse *fuse_new_31(struct fuse_args *args, const struct fuse_operations *op,
130  size_t op_size, void *private_data);
131 int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config);
132 int fuse_session_loop_mt_32(struct fuse_session *se, struct fuse_loop_config *config);
133 
+
void(* fuse_interrupt_func_t)(fuse_req_t req, void *data)
+
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
+ + + +
struct fuse_fs *(* fuse_module_factory_t)(struct fuse_args *args, struct fuse_fs *fs[])
Definition: fuse.h:1226
+ + +
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
+ + + + +
+ + + + diff --git a/doc/html/fuse__kernel_8h_source.html b/doc/html/fuse__kernel_8h_source.html new file mode 100644 index 0000000..628b188 --- /dev/null +++ b/doc/html/fuse__kernel_8h_source.html @@ -0,0 +1,56 @@ + + + + + + + +libfuse: include/fuse_kernel.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_kernel.h
+
+
+
1 /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */
2 /*
3  This file defines the kernel interface of FUSE
4  Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu>
5 
6  This program can be distributed under the terms of the GNU GPL.
7  See the file COPYING.
8 
9  This -- and only this -- header file may also be distributed under
10  the terms of the BSD Licence as follows:
11 
12  Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
13 
14  Redistribution and use in source and binary forms, with or without
15  modification, are permitted provided that the following conditions
16  are met:
17  1. Redistributions of source code must retain the above copyright
18  notice, this list of conditions and the following disclaimer.
19  2. Redistributions in binary form must reproduce the above copyright
20  notice, this list of conditions and the following disclaimer in the
21  documentation and/or other materials provided with the distribution.
22 
23  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
27  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  SUCH DAMAGE.
34 */
35 
36 /*
37  * This file defines the kernel interface of FUSE
38  *
39  * Protocol changelog:
40  *
41  * 7.9:
42  * - new fuse_getattr_in input argument of GETATTR
43  * - add lk_flags in fuse_lk_in
44  * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
45  * - add blksize field to fuse_attr
46  * - add file flags field to fuse_read_in and fuse_write_in
47  *
48  * 7.10
49  * - add nonseekable open flag
50  *
51  * 7.11
52  * - add IOCTL message
53  * - add unsolicited notification support
54  * - add POLL message and NOTIFY_POLL notification
55  *
56  * 7.12
57  * - add umask flag to input argument of open, mknod and mkdir
58  * - add notification messages for invalidation of inodes and
59  * directory entries
60  *
61  * 7.13
62  * - make max number of background requests and congestion threshold
63  * tunables
64  *
65  * 7.14
66  * - add splice support to fuse device
67  *
68  * 7.15
69  * - add store notify
70  * - add retrieve notify
71  *
72  * 7.16
73  * - add BATCH_FORGET request
74  * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct
75  * fuse_ioctl_iovec' instead of ambiguous 'struct iovec'
76  * - add FUSE_IOCTL_32BIT flag
77  *
78  * 7.17
79  * - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK
80  *
81  * 7.18
82  * - add FUSE_IOCTL_DIR flag
83  * - add FUSE_NOTIFY_DELETE
84  *
85  * 7.19
86  * - add FUSE_FALLOCATE
87  *
88  * 7.20
89  * - add FUSE_AUTO_INVAL_DATA
90  *
91  * 7.21
92  * - add FUSE_READDIRPLUS
93  * - send the requested events in POLL request
94  *
95  * 7.22
96  * - add FUSE_ASYNC_DIO
97  *
98  * 7.23
99  * - add FUSE_WRITEBACK_CACHE
100  * - add time_gran to fuse_init_out
101  * - add reserved space to fuse_init_out
102  * - add FATTR_CTIME
103  * - add ctime and ctimensec to fuse_setattr_in
104  * - add FUSE_RENAME2 request
105  * - add FUSE_NO_OPEN_SUPPORT flag
106  *
107  * 7.24
108  * - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support
109  *
110  * 7.25
111  * - add FUSE_PARALLEL_DIROPS
112  *
113  * 7.26
114  * - add FUSE_HANDLE_KILLPRIV
115  * - add FUSE_POSIX_ACL
116  *
117  * 7.27
118  * - add FUSE_ABORT_ERROR
119  *
120  * 7.28
121  * - add FUSE_COPY_FILE_RANGE
122  */
123 
124 #ifndef _LINUX_FUSE_H
125 #define _LINUX_FUSE_H
126 
127 #ifdef __KERNEL__
128 #include <linux/types.h>
129 #else
130 #include <stdint.h>
131 #endif
132 
133 /*
134  * Version negotiation:
135  *
136  * Both the kernel and userspace send the version they support in the
137  * INIT request and reply respectively.
138  *
139  * If the major versions match then both shall use the smallest
140  * of the two minor versions for communication.
141  *
142  * If the kernel supports a larger major version, then userspace shall
143  * reply with the major version it supports, ignore the rest of the
144  * INIT message and expect a new INIT message from the kernel with a
145  * matching major version.
146  *
147  * If the library supports a larger major version, then it shall fall
148  * back to the major protocol version sent by the kernel for
149  * communication and reply with that major version (and an arbitrary
150  * supported minor version).
151  */
152 
154 #define FUSE_KERNEL_VERSION 7
155 
157 #define FUSE_KERNEL_MINOR_VERSION 27
158 
160 #define FUSE_ROOT_ID 1
161 
162 /* Make sure all structures are padded to 64bit boundary, so 32bit
163  userspace works under 64bit kernels */
164 
165 struct fuse_attr {
166  uint64_t ino;
167  uint64_t size;
168  uint64_t blocks;
169  uint64_t atime;
170  uint64_t mtime;
171  uint64_t ctime;
172  uint32_t atimensec;
173  uint32_t mtimensec;
174  uint32_t ctimensec;
175  uint32_t mode;
176  uint32_t nlink;
177  uint32_t uid;
178  uint32_t gid;
179  uint32_t rdev;
180  uint32_t blksize;
181  uint32_t padding;
182 };
183 
184 struct fuse_kstatfs {
185  uint64_t blocks;
186  uint64_t bfree;
187  uint64_t bavail;
188  uint64_t files;
189  uint64_t ffree;
190  uint32_t bsize;
191  uint32_t namelen;
192  uint32_t frsize;
193  uint32_t padding;
194  uint32_t spare[6];
195 };
196 
197 struct fuse_file_lock {
198  uint64_t start;
199  uint64_t end;
200  uint32_t type;
201  uint32_t pid; /* tgid */
202 };
203 
207 #define FATTR_MODE (1 << 0)
208 #define FATTR_UID (1 << 1)
209 #define FATTR_GID (1 << 2)
210 #define FATTR_SIZE (1 << 3)
211 #define FATTR_ATIME (1 << 4)
212 #define FATTR_MTIME (1 << 5)
213 #define FATTR_FH (1 << 6)
214 #define FATTR_ATIME_NOW (1 << 7)
215 #define FATTR_MTIME_NOW (1 << 8)
216 #define FATTR_LOCKOWNER (1 << 9)
217 #define FATTR_CTIME (1 << 10)
218 
226 #define FOPEN_DIRECT_IO (1 << 0)
227 #define FOPEN_KEEP_CACHE (1 << 1)
228 #define FOPEN_NONSEEKABLE (1 << 2)
229 
256 #define FUSE_ASYNC_READ (1 << 0)
257 #define FUSE_POSIX_LOCKS (1 << 1)
258 #define FUSE_FILE_OPS (1 << 2)
259 #define FUSE_ATOMIC_O_TRUNC (1 << 3)
260 #define FUSE_EXPORT_SUPPORT (1 << 4)
261 #define FUSE_BIG_WRITES (1 << 5)
262 #define FUSE_DONT_MASK (1 << 6)
263 #define FUSE_SPLICE_WRITE (1 << 7)
264 #define FUSE_SPLICE_MOVE (1 << 8)
265 #define FUSE_SPLICE_READ (1 << 9)
266 #define FUSE_FLOCK_LOCKS (1 << 10)
267 #define FUSE_HAS_IOCTL_DIR (1 << 11)
268 #define FUSE_AUTO_INVAL_DATA (1 << 12)
269 #define FUSE_DO_READDIRPLUS (1 << 13)
270 #define FUSE_READDIRPLUS_AUTO (1 << 14)
271 #define FUSE_ASYNC_DIO (1 << 15)
272 #define FUSE_WRITEBACK_CACHE (1 << 16)
273 #define FUSE_NO_OPEN_SUPPORT (1 << 17)
274 #define FUSE_PARALLEL_DIROPS (1 << 18)
275 #define FUSE_HANDLE_KILLPRIV (1 << 19)
276 #define FUSE_POSIX_ACL (1 << 20)
277 #define FUSE_ABORT_ERROR (1 << 21)
278 
284 #define CUSE_UNRESTRICTED_IOCTL (1 << 0)
285 
289 #define FUSE_RELEASE_FLUSH (1 << 0)
290 #define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1)
291 
295 #define FUSE_GETATTR_FH (1 << 0)
296 
300 #define FUSE_LK_FLOCK (1 << 0)
301 
308 #define FUSE_WRITE_CACHE (1 << 0)
309 #define FUSE_WRITE_LOCKOWNER (1 << 1)
310 
314 #define FUSE_READ_LOCKOWNER (1 << 1)
315 
327 #define FUSE_IOCTL_COMPAT (1 << 0)
328 #define FUSE_IOCTL_UNRESTRICTED (1 << 1)
329 #define FUSE_IOCTL_RETRY (1 << 2)
330 #define FUSE_IOCTL_32BIT (1 << 3)
331 #define FUSE_IOCTL_DIR (1 << 4)
332 
333 #define FUSE_IOCTL_MAX_IOV 256
334 
340 #define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
341 
342 enum fuse_opcode {
343  FUSE_LOOKUP = 1,
344  FUSE_FORGET = 2, /* no reply */
345  FUSE_GETATTR = 3,
346  FUSE_SETATTR = 4,
347  FUSE_READLINK = 5,
348  FUSE_SYMLINK = 6,
349  FUSE_MKNOD = 8,
350  FUSE_MKDIR = 9,
351  FUSE_UNLINK = 10,
352  FUSE_RMDIR = 11,
353  FUSE_RENAME = 12,
354  FUSE_LINK = 13,
355  FUSE_OPEN = 14,
356  FUSE_READ = 15,
357  FUSE_WRITE = 16,
358  FUSE_STATFS = 17,
359  FUSE_RELEASE = 18,
360  FUSE_FSYNC = 20,
361  FUSE_SETXATTR = 21,
362  FUSE_GETXATTR = 22,
363  FUSE_LISTXATTR = 23,
364  FUSE_REMOVEXATTR = 24,
365  FUSE_FLUSH = 25,
366  FUSE_INIT = 26,
367  FUSE_OPENDIR = 27,
368  FUSE_READDIR = 28,
369  FUSE_RELEASEDIR = 29,
370  FUSE_FSYNCDIR = 30,
371  FUSE_GETLK = 31,
372  FUSE_SETLK = 32,
373  FUSE_SETLKW = 33,
374  FUSE_ACCESS = 34,
375  FUSE_CREATE = 35,
376  FUSE_INTERRUPT = 36,
377  FUSE_BMAP = 37,
378  FUSE_DESTROY = 38,
379  FUSE_IOCTL = 39,
380  FUSE_POLL = 40,
381  FUSE_NOTIFY_REPLY = 41,
382  FUSE_BATCH_FORGET = 42,
383  FUSE_FALLOCATE = 43,
384  FUSE_READDIRPLUS = 44,
385  FUSE_RENAME2 = 45,
386  FUSE_LSEEK = 46,
387  FUSE_COPY_FILE_RANGE = 47,
388 
389  /* CUSE specific operations */
390  CUSE_INIT = 4096,
391 };
392 
393 enum fuse_notify_code {
394  FUSE_NOTIFY_POLL = 1,
395  FUSE_NOTIFY_INVAL_INODE = 2,
396  FUSE_NOTIFY_INVAL_ENTRY = 3,
397  FUSE_NOTIFY_STORE = 4,
398  FUSE_NOTIFY_RETRIEVE = 5,
399  FUSE_NOTIFY_DELETE = 6,
400  FUSE_NOTIFY_CODE_MAX,
401 };
402 
403 /* The read buffer is required to be at least 8k, but may be much larger */
404 #define FUSE_MIN_READ_BUFFER 8192
405 
406 #define FUSE_COMPAT_ENTRY_OUT_SIZE 120
407 
408 struct fuse_entry_out {
409  uint64_t nodeid; /* Inode ID */
410  uint64_t generation; /* Inode generation: nodeid:gen must
411  be unique for the fs's lifetime */
412  uint64_t entry_valid; /* Cache timeout for the name */
413  uint64_t attr_valid; /* Cache timeout for the attributes */
414  uint32_t entry_valid_nsec;
415  uint32_t attr_valid_nsec;
416  struct fuse_attr attr;
417 };
418 
419 struct fuse_forget_in {
420  uint64_t nlookup;
421 };
422 
423 struct fuse_forget_one {
424  uint64_t nodeid;
425  uint64_t nlookup;
426 };
427 
428 struct fuse_batch_forget_in {
429  uint32_t count;
430  uint32_t dummy;
431 };
432 
433 struct fuse_getattr_in {
434  uint32_t getattr_flags;
435  uint32_t dummy;
436  uint64_t fh;
437 };
438 
439 #define FUSE_COMPAT_ATTR_OUT_SIZE 96
440 
441 struct fuse_attr_out {
442  uint64_t attr_valid; /* Cache timeout for the attributes */
443  uint32_t attr_valid_nsec;
444  uint32_t dummy;
445  struct fuse_attr attr;
446 };
447 
448 #define FUSE_COMPAT_MKNOD_IN_SIZE 8
449 
450 struct fuse_mknod_in {
451  uint32_t mode;
452  uint32_t rdev;
453  uint32_t umask;
454  uint32_t padding;
455 };
456 
457 struct fuse_mkdir_in {
458  uint32_t mode;
459  uint32_t umask;
460 };
461 
462 struct fuse_rename_in {
463  uint64_t newdir;
464 };
465 
466 struct fuse_rename2_in {
467  uint64_t newdir;
468  uint32_t flags;
469  uint32_t padding;
470 };
471 
472 struct fuse_link_in {
473  uint64_t oldnodeid;
474 };
475 
476 struct fuse_setattr_in {
477  uint32_t valid;
478  uint32_t padding;
479  uint64_t fh;
480  uint64_t size;
481  uint64_t lock_owner;
482  uint64_t atime;
483  uint64_t mtime;
484  uint64_t ctime;
485  uint32_t atimensec;
486  uint32_t mtimensec;
487  uint32_t ctimensec;
488  uint32_t mode;
489  uint32_t unused4;
490  uint32_t uid;
491  uint32_t gid;
492  uint32_t unused5;
493 };
494 
495 struct fuse_open_in {
496  uint32_t flags;
497  uint32_t unused;
498 };
499 
500 struct fuse_create_in {
501  uint32_t flags;
502  uint32_t mode;
503  uint32_t umask;
504  uint32_t padding;
505 };
506 
507 struct fuse_open_out {
508  uint64_t fh;
509  uint32_t open_flags;
510  uint32_t padding;
511 };
512 
513 struct fuse_release_in {
514  uint64_t fh;
515  uint32_t flags;
516  uint32_t release_flags;
517  uint64_t lock_owner;
518 };
519 
520 struct fuse_flush_in {
521  uint64_t fh;
522  uint32_t unused;
523  uint32_t padding;
524  uint64_t lock_owner;
525 };
526 
527 struct fuse_read_in {
528  uint64_t fh;
529  uint64_t offset;
530  uint32_t size;
531  uint32_t read_flags;
532  uint64_t lock_owner;
533  uint32_t flags;
534  uint32_t padding;
535 };
536 
537 #define FUSE_COMPAT_WRITE_IN_SIZE 24
538 
539 struct fuse_write_in {
540  uint64_t fh;
541  uint64_t offset;
542  uint32_t size;
543  uint32_t write_flags;
544  uint64_t lock_owner;
545  uint32_t flags;
546  uint32_t padding;
547 };
548 
549 struct fuse_write_out {
550  uint32_t size;
551  uint32_t padding;
552 };
553 
554 #define FUSE_COMPAT_STATFS_SIZE 48
555 
556 struct fuse_statfs_out {
557  struct fuse_kstatfs st;
558 };
559 
560 struct fuse_fsync_in {
561  uint64_t fh;
562  uint32_t fsync_flags;
563  uint32_t padding;
564 };
565 
566 struct fuse_setxattr_in {
567  uint32_t size;
568  uint32_t flags;
569 };
570 
571 struct fuse_getxattr_in {
572  uint32_t size;
573  uint32_t padding;
574 };
575 
576 struct fuse_getxattr_out {
577  uint32_t size;
578  uint32_t padding;
579 };
580 
581 struct fuse_lk_in {
582  uint64_t fh;
583  uint64_t owner;
584  struct fuse_file_lock lk;
585  uint32_t lk_flags;
586  uint32_t padding;
587 };
588 
589 struct fuse_lk_out {
590  struct fuse_file_lock lk;
591 };
592 
593 struct fuse_access_in {
594  uint32_t mask;
595  uint32_t padding;
596 };
597 
598 struct fuse_init_in {
599  uint32_t major;
600  uint32_t minor;
601  uint32_t max_readahead;
602  uint32_t flags;
603 };
604 
605 #define FUSE_COMPAT_INIT_OUT_SIZE 8
606 #define FUSE_COMPAT_22_INIT_OUT_SIZE 24
607 
608 struct fuse_init_out {
609  uint32_t major;
610  uint32_t minor;
611  uint32_t max_readahead;
612  uint32_t flags;
613  uint16_t max_background;
614  uint16_t congestion_threshold;
615  uint32_t max_write;
616  uint32_t time_gran;
617  uint32_t unused[9];
618 };
619 
620 #define CUSE_INIT_INFO_MAX 4096
621 
622 struct cuse_init_in {
623  uint32_t major;
624  uint32_t minor;
625  uint32_t unused;
626  uint32_t flags;
627 };
628 
629 struct cuse_init_out {
630  uint32_t major;
631  uint32_t minor;
632  uint32_t unused;
633  uint32_t flags;
634  uint32_t max_read;
635  uint32_t max_write;
636  uint32_t dev_major; /* chardev major */
637  uint32_t dev_minor; /* chardev minor */
638  uint32_t spare[10];
639 };
640 
641 struct fuse_interrupt_in {
642  uint64_t unique;
643 };
644 
645 struct fuse_bmap_in {
646  uint64_t block;
647  uint32_t blocksize;
648  uint32_t padding;
649 };
650 
651 struct fuse_bmap_out {
652  uint64_t block;
653 };
654 
655 struct fuse_ioctl_in {
656  uint64_t fh;
657  uint32_t flags;
658  uint32_t cmd;
659  uint64_t arg;
660  uint32_t in_size;
661  uint32_t out_size;
662 };
663 
664 struct fuse_ioctl_iovec {
665  uint64_t base;
666  uint64_t len;
667 };
668 
669 struct fuse_ioctl_out {
670  int32_t result;
671  uint32_t flags;
672  uint32_t in_iovs;
673  uint32_t out_iovs;
674 };
675 
676 struct fuse_poll_in {
677  uint64_t fh;
678  uint64_t kh;
679  uint32_t flags;
680  uint32_t events;
681 };
682 
683 struct fuse_poll_out {
684  uint32_t revents;
685  uint32_t padding;
686 };
687 
688 struct fuse_notify_poll_wakeup_out {
689  uint64_t kh;
690 };
691 
692 struct fuse_fallocate_in {
693  uint64_t fh;
694  uint64_t offset;
695  uint64_t length;
696  uint32_t mode;
697  uint32_t padding;
698 };
699 
700 struct fuse_in_header {
701  uint32_t len;
702  uint32_t opcode;
703  uint64_t unique;
704  uint64_t nodeid;
705  uint32_t uid;
706  uint32_t gid;
707  uint32_t pid;
708  uint32_t padding;
709 };
710 
711 struct fuse_out_header {
712  uint32_t len;
713  int32_t error;
714  uint64_t unique;
715 };
716 
717 struct fuse_dirent {
718  uint64_t ino;
719  uint64_t off;
720  uint32_t namelen;
721  uint32_t type;
722  char name[];
723 };
724 
725 #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
726 #define FUSE_DIRENT_ALIGN(x) \
727  (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1))
728 #define FUSE_DIRENT_SIZE(d) \
729  FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
730 
731 struct fuse_direntplus {
732  struct fuse_entry_out entry_out;
733  struct fuse_dirent dirent;
734 };
735 
736 #define FUSE_NAME_OFFSET_DIRENTPLUS \
737  offsetof(struct fuse_direntplus, dirent.name)
738 #define FUSE_DIRENTPLUS_SIZE(d) \
739  FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen)
740 
741 struct fuse_notify_inval_inode_out {
742  uint64_t ino;
743  int64_t off;
744  int64_t len;
745 };
746 
747 struct fuse_notify_inval_entry_out {
748  uint64_t parent;
749  uint32_t namelen;
750  uint32_t padding;
751 };
752 
753 struct fuse_notify_delete_out {
754  uint64_t parent;
755  uint64_t child;
756  uint32_t namelen;
757  uint32_t padding;
758 };
759 
760 struct fuse_notify_store_out {
761  uint64_t nodeid;
762  uint64_t offset;
763  uint32_t size;
764  uint32_t padding;
765 };
766 
767 struct fuse_notify_retrieve_out {
768  uint64_t notify_unique;
769  uint64_t nodeid;
770  uint64_t offset;
771  uint32_t size;
772  uint32_t padding;
773 };
774 
775 /* Matches the size of fuse_write_in */
776 struct fuse_notify_retrieve_in {
777  uint64_t dummy1;
778  uint64_t offset;
779  uint32_t size;
780  uint32_t dummy2;
781  uint64_t dummy3;
782  uint64_t dummy4;
783 };
784 
785 /* Device ioctls: */
786 #define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t)
787 
788 struct fuse_lseek_in {
789  uint64_t fh;
790  uint64_t offset;
791  uint32_t whence;
792  uint32_t padding;
793 };
794 
795 struct fuse_lseek_out {
796  uint64_t offset;
797 };
798 
799 struct fuse_copy_file_range_in {
800  uint64_t fh_in;
801  uint64_t off_in;
802  uint64_t nodeid_out;
803  uint64_t fh_out;
804  uint64_t off_out;
805  uint64_t len;
806  uint64_t flags;
807 };
808 
809 #endif /* _LINUX_FUSE_H */
+ + + + diff --git a/doc/html/fuse__loop_8c_source.html b/doc/html/fuse__loop_8c_source.html new file mode 100644 index 0000000..095769f --- /dev/null +++ b/doc/html/fuse__loop_8c_source.html @@ -0,0 +1,62 @@ + + + + + + + +libfuse: lib/fuse_loop.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_loop.c
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Implementation of the single-threaded FUSE session loop.
6 
7  This program can be distributed under the terms of the GNU LGPLv2.
8  See the file COPYING.LIB
9 */
10 
11 #include "config.h"
12 #include "fuse_lowlevel.h"
13 #include "fuse_i.h"
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <errno.h>
18 
19 int fuse_session_loop(struct fuse_session *se)
20 {
21  int res = 0;
22  struct fuse_buf fbuf = {
23  .mem = NULL,
24  };
25 
26  while (!fuse_session_exited(se)) {
27  res = fuse_session_receive_buf_int(se, &fbuf, NULL);
28 
29  if (res == -EINTR)
30  continue;
31  if (res <= 0)
32  break;
33 
34  fuse_session_process_buf_int(se, &fbuf, NULL);
35  }
36 
37  free(fbuf.mem);
38  if(res > 0)
39  /* No error, just the length of the most recently read
40  request */
41  res = 0;
42  if(se->error != 0)
43  res = se->error;
45  return res;
46 }
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
+
int fuse_session_exited(struct fuse_session *se)
+
void fuse_session_reset(struct fuse_session *se)
+
void * mem
Definition: fuse_common.h:640
+ + +
+ + + + diff --git a/doc/html/fuse__loop__mt_8c_source.html b/doc/html/fuse__loop__mt_8c_source.html new file mode 100644 index 0000000..2cc1597 --- /dev/null +++ b/doc/html/fuse__loop__mt_8c_source.html @@ -0,0 +1,66 @@ + + + + + + + +libfuse: lib/fuse_loop_mt.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_loop_mt.c
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Implementation of the multi-threaded FUSE session loop.
6 
7  This program can be distributed under the terms of the GNU LGPLv2.
8  See the file COPYING.LIB.
9 */
10 
11 #include "config.h"
12 #include "fuse_lowlevel.h"
13 #include "fuse_misc.h"
14 #include "fuse_kernel.h"
15 #include "fuse_i.h"
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <signal.h>
22 #include <semaphore.h>
23 #include <errno.h>
24 #include <sys/time.h>
25 #include <sys/ioctl.h>
26 #include <assert.h>
27 
28 /* Environment var controlling the thread stack size */
29 #define ENVNAME_THREAD_STACK "FUSE_THREAD_STACK"
30 
31 struct fuse_worker {
32  struct fuse_worker *prev;
33  struct fuse_worker *next;
34  pthread_t thread_id;
35  size_t bufsize;
36 
37  // We need to include fuse_buf so that we can properly free
38  // it when a thread is terminated by pthread_cancel().
39  struct fuse_buf fbuf;
40  struct fuse_chan *ch;
41  struct fuse_mt *mt;
42 };
43 
44 struct fuse_mt {
45  pthread_mutex_t lock;
46  int numworker;
47  int numavail;
48  struct fuse_session *se;
49  struct fuse_worker main;
50  sem_t finish;
51  int exit;
52  int error;
53  int clone_fd;
54  int max_idle;
55 };
56 
57 static struct fuse_chan *fuse_chan_new(int fd)
58 {
59  struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
60  if (ch == NULL) {
61  fprintf(stderr, "fuse: failed to allocate channel\n");
62  return NULL;
63  }
64 
65  memset(ch, 0, sizeof(*ch));
66  ch->fd = fd;
67  ch->ctr = 1;
68  fuse_mutex_init(&ch->lock);
69 
70  return ch;
71 }
72 
73 struct fuse_chan *fuse_chan_get(struct fuse_chan *ch)
74 {
75  assert(ch->ctr > 0);
76  pthread_mutex_lock(&ch->lock);
77  ch->ctr++;
78  pthread_mutex_unlock(&ch->lock);
79 
80  return ch;
81 }
82 
83 void fuse_chan_put(struct fuse_chan *ch)
84 {
85  if (ch == NULL)
86  return;
87  pthread_mutex_lock(&ch->lock);
88  ch->ctr--;
89  if (!ch->ctr) {
90  pthread_mutex_unlock(&ch->lock);
91  close(ch->fd);
92  pthread_mutex_destroy(&ch->lock);
93  free(ch);
94  } else
95  pthread_mutex_unlock(&ch->lock);
96 }
97 
98 static void list_add_worker(struct fuse_worker *w, struct fuse_worker *next)
99 {
100  struct fuse_worker *prev = next->prev;
101  w->next = next;
102  w->prev = prev;
103  prev->next = w;
104  next->prev = w;
105 }
106 
107 static void list_del_worker(struct fuse_worker *w)
108 {
109  struct fuse_worker *prev = w->prev;
110  struct fuse_worker *next = w->next;
111  prev->next = next;
112  next->prev = prev;
113 }
114 
115 static int fuse_loop_start_thread(struct fuse_mt *mt);
116 
117 static void *fuse_do_work(void *data)
118 {
119  struct fuse_worker *w = (struct fuse_worker *) data;
120  struct fuse_mt *mt = w->mt;
121 
122  while (!fuse_session_exited(mt->se)) {
123  int isforget = 0;
124  int res;
125 
126  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
127  res = fuse_session_receive_buf_int(mt->se, &w->fbuf, w->ch);
128  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
129  if (res == -EINTR)
130  continue;
131  if (res <= 0) {
132  if (res < 0) {
133  fuse_session_exit(mt->se);
134  mt->error = res;
135  }
136  break;
137  }
138 
139  pthread_mutex_lock(&mt->lock);
140  if (mt->exit) {
141  pthread_mutex_unlock(&mt->lock);
142  return NULL;
143  }
144 
145  /*
146  * This disgusting hack is needed so that zillions of threads
147  * are not created on a burst of FORGET messages
148  */
149  if (!(w->fbuf.flags & FUSE_BUF_IS_FD)) {
150  struct fuse_in_header *in = w->fbuf.mem;
151 
152  if (in->opcode == FUSE_FORGET ||
153  in->opcode == FUSE_BATCH_FORGET)
154  isforget = 1;
155  }
156 
157  if (!isforget)
158  mt->numavail--;
159  if (mt->numavail == 0)
160  fuse_loop_start_thread(mt);
161  pthread_mutex_unlock(&mt->lock);
162 
163  fuse_session_process_buf_int(mt->se, &w->fbuf, w->ch);
164 
165  pthread_mutex_lock(&mt->lock);
166  if (!isforget)
167  mt->numavail++;
168  if (mt->numavail > mt->max_idle) {
169  if (mt->exit) {
170  pthread_mutex_unlock(&mt->lock);
171  return NULL;
172  }
173  list_del_worker(w);
174  mt->numavail--;
175  mt->numworker--;
176  pthread_mutex_unlock(&mt->lock);
177 
178  pthread_detach(w->thread_id);
179  free(w->fbuf.mem);
180  fuse_chan_put(w->ch);
181  free(w);
182  return NULL;
183  }
184  pthread_mutex_unlock(&mt->lock);
185  }
186 
187  sem_post(&mt->finish);
188 
189  return NULL;
190 }
191 
192 int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg)
193 {
194  sigset_t oldset;
195  sigset_t newset;
196  int res;
197  pthread_attr_t attr;
198  char *stack_size;
199 
200  /* Override default stack size */
201  pthread_attr_init(&attr);
202  stack_size = getenv(ENVNAME_THREAD_STACK);
203  if (stack_size && pthread_attr_setstacksize(&attr, atoi(stack_size)))
204  fprintf(stderr, "fuse: invalid stack size: %s\n", stack_size);
205 
206  /* Disallow signal reception in worker threads */
207  sigemptyset(&newset);
208  sigaddset(&newset, SIGTERM);
209  sigaddset(&newset, SIGINT);
210  sigaddset(&newset, SIGHUP);
211  sigaddset(&newset, SIGQUIT);
212  pthread_sigmask(SIG_BLOCK, &newset, &oldset);
213  res = pthread_create(thread_id, &attr, func, arg);
214  pthread_sigmask(SIG_SETMASK, &oldset, NULL);
215  pthread_attr_destroy(&attr);
216  if (res != 0) {
217  fprintf(stderr, "fuse: error creating thread: %s\n",
218  strerror(res));
219  return -1;
220  }
221 
222  return 0;
223 }
224 
225 static struct fuse_chan *fuse_clone_chan(struct fuse_mt *mt)
226 {
227  int res;
228  int clonefd;
229  uint32_t masterfd;
230  struct fuse_chan *newch;
231  const char *devname = "/dev/fuse";
232 
233 #ifndef O_CLOEXEC
234 #define O_CLOEXEC 0
235 #endif
236  clonefd = open(devname, O_RDWR | O_CLOEXEC);
237  if (clonefd == -1) {
238  fprintf(stderr, "fuse: failed to open %s: %s\n", devname,
239  strerror(errno));
240  return NULL;
241  }
242  fcntl(clonefd, F_SETFD, FD_CLOEXEC);
243 
244  masterfd = mt->se->fd;
245  res = ioctl(clonefd, FUSE_DEV_IOC_CLONE, &masterfd);
246  if (res == -1) {
247  fprintf(stderr, "fuse: failed to clone device fd: %s\n",
248  strerror(errno));
249  close(clonefd);
250  return NULL;
251  }
252  newch = fuse_chan_new(clonefd);
253  if (newch == NULL)
254  close(clonefd);
255 
256  return newch;
257 }
258 
259 static int fuse_loop_start_thread(struct fuse_mt *mt)
260 {
261  int res;
262 
263  struct fuse_worker *w = malloc(sizeof(struct fuse_worker));
264  if (!w) {
265  fprintf(stderr, "fuse: failed to allocate worker structure\n");
266  return -1;
267  }
268  memset(w, 0, sizeof(struct fuse_worker));
269  w->fbuf.mem = NULL;
270  w->mt = mt;
271 
272  w->ch = NULL;
273  if (mt->clone_fd) {
274  w->ch = fuse_clone_chan(mt);
275  if(!w->ch) {
276  /* Don't attempt this again */
277  fprintf(stderr, "fuse: trying to continue "
278  "without -o clone_fd.\n");
279  mt->clone_fd = 0;
280  }
281  }
282 
283  res = fuse_start_thread(&w->thread_id, fuse_do_work, w);
284  if (res == -1) {
285  fuse_chan_put(w->ch);
286  free(w);
287  return -1;
288  }
289  list_add_worker(w, &mt->main);
290  mt->numavail ++;
291  mt->numworker ++;
292 
293  return 0;
294 }
295 
296 static void fuse_join_worker(struct fuse_mt *mt, struct fuse_worker *w)
297 {
298  pthread_join(w->thread_id, NULL);
299  pthread_mutex_lock(&mt->lock);
300  list_del_worker(w);
301  pthread_mutex_unlock(&mt->lock);
302  free(w->fbuf.mem);
303  fuse_chan_put(w->ch);
304  free(w);
305 }
306 
307 FUSE_SYMVER(".symver fuse_session_loop_mt_32,fuse_session_loop_mt@@FUSE_3.2");
308 int fuse_session_loop_mt_32(struct fuse_session *se, struct fuse_loop_config *config)
309 {
310  int err;
311  struct fuse_mt mt;
312  struct fuse_worker *w;
313 
314  memset(&mt, 0, sizeof(struct fuse_mt));
315  mt.se = se;
316  mt.clone_fd = config->clone_fd;
317  mt.error = 0;
318  mt.numworker = 0;
319  mt.numavail = 0;
320  mt.max_idle = config->max_idle_threads;
321  mt.main.thread_id = pthread_self();
322  mt.main.prev = mt.main.next = &mt.main;
323  sem_init(&mt.finish, 0, 0);
324  fuse_mutex_init(&mt.lock);
325 
326  pthread_mutex_lock(&mt.lock);
327  err = fuse_loop_start_thread(&mt);
328  pthread_mutex_unlock(&mt.lock);
329  if (!err) {
330  /* sem_wait() is interruptible */
331  while (!fuse_session_exited(se))
332  sem_wait(&mt.finish);
333 
334  pthread_mutex_lock(&mt.lock);
335  for (w = mt.main.next; w != &mt.main; w = w->next)
336  pthread_cancel(w->thread_id);
337  mt.exit = 1;
338  pthread_mutex_unlock(&mt.lock);
339 
340  while (mt.main.next != &mt.main)
341  fuse_join_worker(&mt, mt.main.next);
342 
343  err = mt.error;
344  }
345 
346  pthread_mutex_destroy(&mt.lock);
347  sem_destroy(&mt.finish);
348  if(se->error != 0)
349  err = se->error;
350  fuse_session_reset(se);
351  return err;
352 }
353 
354 int fuse_session_loop_mt_31(struct fuse_session *se, int clone_fd);
355 FUSE_SYMVER(".symver fuse_session_loop_mt_31,fuse_session_loop_mt@FUSE_3.0");
356 int fuse_session_loop_mt_31(struct fuse_session *se, int clone_fd)
357 {
358  struct fuse_loop_config config;
359  config.clone_fd = clone_fd;
360  config.max_idle_threads = 10;
361  return fuse_session_loop_mt_32(se, &config);
362 }
void fuse_session_exit(struct fuse_session *se)
+ +
unsigned int max_idle_threads
Definition: fuse_common.h:103
+
int fuse_session_loop_mt_31(struct fuse_session *se, int clone_fd)
Definition: fuse_loop_mt.c:356
+
int fuse_session_exited(struct fuse_session *se)
+
void fuse_session_reset(struct fuse_session *se)
+ + + + +
+ + + + diff --git a/doc/html/fuse__lowlevel_8c_source.html b/doc/html/fuse__lowlevel_8c_source.html new file mode 100644 index 0000000..1b4f858 --- /dev/null +++ b/doc/html/fuse__lowlevel_8c_source.html @@ -0,0 +1,168 @@ + + + + + + + +libfuse: lib/fuse_lowlevel.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_lowlevel.c
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Implementation of (most of) the low-level FUSE API. The session loop
6  functions are implemented in separate files.
7 
8  This program can be distributed under the terms of the GNU LGPLv2.
9  See the file COPYING.LIB
10 */
11 
12 #define _GNU_SOURCE
13 
14 #include "config.h"
15 #include "fuse_i.h"
16 #include "fuse_kernel.h"
17 #include "fuse_opt.h"
18 #include "fuse_misc.h"
19 #include "mount_util.h"
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stddef.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <limits.h>
27 #include <errno.h>
28 #include <assert.h>
29 #include <sys/file.h>
30 
31 #ifndef F_LINUX_SPECIFIC_BASE
32 #define F_LINUX_SPECIFIC_BASE 1024
33 #endif
34 #ifndef F_SETPIPE_SZ
35 #define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
36 #endif
37 
38 
39 #define PARAM(inarg) (((char *)(inarg)) + sizeof(*(inarg)))
40 #define OFFSET_MAX 0x7fffffffffffffffLL
41 
42 #define container_of(ptr, type, member) ({ \
43  const typeof( ((type *)0)->member ) *__mptr = (ptr); \
44  (type *)( (char *)__mptr - offsetof(type,member) );})
45 
46 struct fuse_pollhandle {
47  uint64_t kh;
48  struct fuse_session *se;
49 };
50 
51 static size_t pagesize;
52 
53 static __attribute__((constructor)) void fuse_ll_init_pagesize(void)
54 {
55  pagesize = getpagesize();
56 }
57 
58 static void convert_stat(const struct stat *stbuf, struct fuse_attr *attr)
59 {
60  attr->ino = stbuf->st_ino;
61  attr->mode = stbuf->st_mode;
62  attr->nlink = stbuf->st_nlink;
63  attr->uid = stbuf->st_uid;
64  attr->gid = stbuf->st_gid;
65  attr->rdev = stbuf->st_rdev;
66  attr->size = stbuf->st_size;
67  attr->blksize = stbuf->st_blksize;
68  attr->blocks = stbuf->st_blocks;
69  attr->atime = stbuf->st_atime;
70  attr->mtime = stbuf->st_mtime;
71  attr->ctime = stbuf->st_ctime;
72  attr->atimensec = ST_ATIM_NSEC(stbuf);
73  attr->mtimensec = ST_MTIM_NSEC(stbuf);
74  attr->ctimensec = ST_CTIM_NSEC(stbuf);
75 }
76 
77 static void convert_attr(const struct fuse_setattr_in *attr, struct stat *stbuf)
78 {
79  stbuf->st_mode = attr->mode;
80  stbuf->st_uid = attr->uid;
81  stbuf->st_gid = attr->gid;
82  stbuf->st_size = attr->size;
83  stbuf->st_atime = attr->atime;
84  stbuf->st_mtime = attr->mtime;
85  stbuf->st_ctime = attr->ctime;
86  ST_ATIM_NSEC_SET(stbuf, attr->atimensec);
87  ST_MTIM_NSEC_SET(stbuf, attr->mtimensec);
88  ST_CTIM_NSEC_SET(stbuf, attr->ctimensec);
89 }
90 
91 static size_t iov_length(const struct iovec *iov, size_t count)
92 {
93  size_t seg;
94  size_t ret = 0;
95 
96  for (seg = 0; seg < count; seg++)
97  ret += iov[seg].iov_len;
98  return ret;
99 }
100 
101 static void list_init_req(struct fuse_req *req)
102 {
103  req->next = req;
104  req->prev = req;
105 }
106 
107 static void list_del_req(struct fuse_req *req)
108 {
109  struct fuse_req *prev = req->prev;
110  struct fuse_req *next = req->next;
111  prev->next = next;
112  next->prev = prev;
113 }
114 
115 static void list_add_req(struct fuse_req *req, struct fuse_req *next)
116 {
117  struct fuse_req *prev = next->prev;
118  req->next = next;
119  req->prev = prev;
120  prev->next = req;
121  next->prev = req;
122 }
123 
124 static void destroy_req(fuse_req_t req)
125 {
126  pthread_mutex_destroy(&req->lock);
127  free(req);
128 }
129 
130 void fuse_free_req(fuse_req_t req)
131 {
132  int ctr;
133  struct fuse_session *se = req->se;
134 
135  pthread_mutex_lock(&se->lock);
136  req->u.ni.func = NULL;
137  req->u.ni.data = NULL;
138  list_del_req(req);
139  ctr = --req->ctr;
140  fuse_chan_put(req->ch);
141  req->ch = NULL;
142  pthread_mutex_unlock(&se->lock);
143  if (!ctr)
144  destroy_req(req);
145 }
146 
147 static struct fuse_req *fuse_ll_alloc_req(struct fuse_session *se)
148 {
149  struct fuse_req *req;
150 
151  req = (struct fuse_req *) calloc(1, sizeof(struct fuse_req));
152  if (req == NULL) {
153  fprintf(stderr, "fuse: failed to allocate request\n");
154  } else {
155  req->se = se;
156  req->ctr = 1;
157  list_init_req(req);
158  fuse_mutex_init(&req->lock);
159  }
160 
161  return req;
162 }
163 
164 /* Send data. If *ch* is NULL, send via session master fd */
165 static int fuse_send_msg(struct fuse_session *se, struct fuse_chan *ch,
166  struct iovec *iov, int count)
167 {
168  struct fuse_out_header *out = iov[0].iov_base;
169 
170  out->len = iov_length(iov, count);
171  if (se->debug) {
172  if (out->unique == 0) {
173  fprintf(stderr, "NOTIFY: code=%d length=%u\n",
174  out->error, out->len);
175  } else if (out->error) {
176  fprintf(stderr,
177  " unique: %llu, error: %i (%s), outsize: %i\n",
178  (unsigned long long) out->unique, out->error,
179  strerror(-out->error), out->len);
180  } else {
181  fprintf(stderr,
182  " unique: %llu, success, outsize: %i\n",
183  (unsigned long long) out->unique, out->len);
184  }
185  }
186 
187  ssize_t res = writev(ch ? ch->fd : se->fd,
188  iov, count);
189  int err = errno;
190 
191  if (res == -1) {
192  assert(se != NULL);
193 
194  /* ENOENT means the operation was interrupted */
195  if (!fuse_session_exited(se) && err != ENOENT)
196  perror("fuse: writing device");
197  return -err;
198  }
199 
200  return 0;
201 }
202 
203 
204 int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
205  int count)
206 {
207  struct fuse_out_header out;
208 
209  if (error <= -1000 || error > 0) {
210  fprintf(stderr, "fuse: bad error value: %i\n", error);
211  error = -ERANGE;
212  }
213 
214  out.unique = req->unique;
215  out.error = error;
216 
217  iov[0].iov_base = &out;
218  iov[0].iov_len = sizeof(struct fuse_out_header);
219 
220  return fuse_send_msg(req->se, req->ch, iov, count);
221 }
222 
223 static int send_reply_iov(fuse_req_t req, int error, struct iovec *iov,
224  int count)
225 {
226  int res;
227 
228  res = fuse_send_reply_iov_nofree(req, error, iov, count);
229  fuse_free_req(req);
230  return res;
231 }
232 
233 static int send_reply(fuse_req_t req, int error, const void *arg,
234  size_t argsize)
235 {
236  struct iovec iov[2];
237  int count = 1;
238  if (argsize) {
239  iov[1].iov_base = (void *) arg;
240  iov[1].iov_len = argsize;
241  count++;
242  }
243  return send_reply_iov(req, error, iov, count);
244 }
245 
246 int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
247 {
248  int res;
249  struct iovec *padded_iov;
250 
251  padded_iov = malloc((count + 1) * sizeof(struct iovec));
252  if (padded_iov == NULL)
253  return fuse_reply_err(req, ENOMEM);
254 
255  memcpy(padded_iov + 1, iov, count * sizeof(struct iovec));
256  count++;
257 
258  res = send_reply_iov(req, 0, padded_iov, count);
259  free(padded_iov);
260 
261  return res;
262 }
263 
264 
265 /* `buf` is allowed to be empty so that the proper size may be
266  allocated by the caller */
267 size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize,
268  const char *name, const struct stat *stbuf, off_t off)
269 {
270  (void)req;
271  size_t namelen;
272  size_t entlen;
273  size_t entlen_padded;
274  struct fuse_dirent *dirent;
275 
276  namelen = strlen(name);
277  entlen = FUSE_NAME_OFFSET + namelen;
278  entlen_padded = FUSE_DIRENT_ALIGN(entlen);
279 
280  if ((buf == NULL) || (entlen_padded > bufsize))
281  return entlen_padded;
282 
283  dirent = (struct fuse_dirent*) buf;
284  dirent->ino = stbuf->st_ino;
285  dirent->off = off;
286  dirent->namelen = namelen;
287  dirent->type = (stbuf->st_mode & 0170000) >> 12;
288  strncpy(dirent->name, name, namelen);
289  memset(dirent->name + namelen, 0, entlen_padded - entlen);
290 
291  return entlen_padded;
292 }
293 
294 static void convert_statfs(const struct statvfs *stbuf,
295  struct fuse_kstatfs *kstatfs)
296 {
297  kstatfs->bsize = stbuf->f_bsize;
298  kstatfs->frsize = stbuf->f_frsize;
299  kstatfs->blocks = stbuf->f_blocks;
300  kstatfs->bfree = stbuf->f_bfree;
301  kstatfs->bavail = stbuf->f_bavail;
302  kstatfs->files = stbuf->f_files;
303  kstatfs->ffree = stbuf->f_ffree;
304  kstatfs->namelen = stbuf->f_namemax;
305 }
306 
307 static int send_reply_ok(fuse_req_t req, const void *arg, size_t argsize)
308 {
309  return send_reply(req, 0, arg, argsize);
310 }
311 
312 int fuse_reply_err(fuse_req_t req, int err)
313 {
314  return send_reply(req, -err, NULL, 0);
315 }
316 
318 {
319  fuse_free_req(req);
320 }
321 
322 static unsigned long calc_timeout_sec(double t)
323 {
324  if (t > (double) ULONG_MAX)
325  return ULONG_MAX;
326  else if (t < 0.0)
327  return 0;
328  else
329  return (unsigned long) t;
330 }
331 
332 static unsigned int calc_timeout_nsec(double t)
333 {
334  double f = t - (double) calc_timeout_sec(t);
335  if (f < 0.0)
336  return 0;
337  else if (f >= 0.999999999)
338  return 999999999;
339  else
340  return (unsigned int) (f * 1.0e9);
341 }
342 
343 static void fill_entry(struct fuse_entry_out *arg,
344  const struct fuse_entry_param *e)
345 {
346  arg->nodeid = e->ino;
347  arg->generation = e->generation;
348  arg->entry_valid = calc_timeout_sec(e->entry_timeout);
349  arg->entry_valid_nsec = calc_timeout_nsec(e->entry_timeout);
350  arg->attr_valid = calc_timeout_sec(e->attr_timeout);
351  arg->attr_valid_nsec = calc_timeout_nsec(e->attr_timeout);
352  convert_stat(&e->attr, &arg->attr);
353 }
354 
355 /* `buf` is allowed to be empty so that the proper size may be
356  allocated by the caller */
357 size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize,
358  const char *name,
359  const struct fuse_entry_param *e, off_t off)
360 {
361  (void)req;
362  size_t namelen;
363  size_t entlen;
364  size_t entlen_padded;
365 
366  namelen = strlen(name);
367  entlen = FUSE_NAME_OFFSET_DIRENTPLUS + namelen;
368  entlen_padded = FUSE_DIRENT_ALIGN(entlen);
369  if ((buf == NULL) || (entlen_padded > bufsize))
370  return entlen_padded;
371 
372  struct fuse_direntplus *dp = (struct fuse_direntplus *) buf;
373  memset(&dp->entry_out, 0, sizeof(dp->entry_out));
374  fill_entry(&dp->entry_out, e);
375 
376  struct fuse_dirent *dirent = &dp->dirent;
377  dirent->ino = e->attr.st_ino;
378  dirent->off = off;
379  dirent->namelen = namelen;
380  dirent->type = (e->attr.st_mode & 0170000) >> 12;
381  strncpy(dirent->name, name, namelen);
382  memset(dirent->name + namelen, 0, entlen_padded - entlen);
383 
384  return entlen_padded;
385 }
386 
387 static void fill_open(struct fuse_open_out *arg,
388  const struct fuse_file_info *f)
389 {
390  arg->fh = f->fh;
391  if (f->direct_io)
392  arg->open_flags |= FOPEN_DIRECT_IO;
393  if (f->keep_cache)
394  arg->open_flags |= FOPEN_KEEP_CACHE;
395  if (f->nonseekable)
396  arg->open_flags |= FOPEN_NONSEEKABLE;
397 }
398 
400 {
401  struct fuse_entry_out arg;
402  size_t size = req->se->conn.proto_minor < 9 ?
403  FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(arg);
404 
405  /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant
406  negative entry */
407  if (!e->ino && req->se->conn.proto_minor < 4)
408  return fuse_reply_err(req, ENOENT);
409 
410  memset(&arg, 0, sizeof(arg));
411  fill_entry(&arg, e);
412  return send_reply_ok(req, &arg, size);
413 }
414 
416  const struct fuse_file_info *f)
417 {
418  char buf[sizeof(struct fuse_entry_out) + sizeof(struct fuse_open_out)];
419  size_t entrysize = req->se->conn.proto_minor < 9 ?
420  FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(struct fuse_entry_out);
421  struct fuse_entry_out *earg = (struct fuse_entry_out *) buf;
422  struct fuse_open_out *oarg = (struct fuse_open_out *) (buf + entrysize);
423 
424  memset(buf, 0, sizeof(buf));
425  fill_entry(earg, e);
426  fill_open(oarg, f);
427  return send_reply_ok(req, buf,
428  entrysize + sizeof(struct fuse_open_out));
429 }
430 
431 int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
432  double attr_timeout)
433 {
434  struct fuse_attr_out arg;
435  size_t size = req->se->conn.proto_minor < 9 ?
436  FUSE_COMPAT_ATTR_OUT_SIZE : sizeof(arg);
437 
438  memset(&arg, 0, sizeof(arg));
439  arg.attr_valid = calc_timeout_sec(attr_timeout);
440  arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout);
441  convert_stat(attr, &arg.attr);
442 
443  return send_reply_ok(req, &arg, size);
444 }
445 
446 int fuse_reply_readlink(fuse_req_t req, const char *linkname)
447 {
448  return send_reply_ok(req, linkname, strlen(linkname));
449 }
450 
451 int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *f)
452 {
453  struct fuse_open_out arg;
454 
455  memset(&arg, 0, sizeof(arg));
456  fill_open(&arg, f);
457  return send_reply_ok(req, &arg, sizeof(arg));
458 }
459 
460 int fuse_reply_write(fuse_req_t req, size_t count)
461 {
462  struct fuse_write_out arg;
463 
464  memset(&arg, 0, sizeof(arg));
465  arg.size = count;
466 
467  return send_reply_ok(req, &arg, sizeof(arg));
468 }
469 
470 int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
471 {
472  return send_reply_ok(req, buf, size);
473 }
474 
475 static int fuse_send_data_iov_fallback(struct fuse_session *se,
476  struct fuse_chan *ch,
477  struct iovec *iov, int iov_count,
478  struct fuse_bufvec *buf,
479  size_t len)
480 {
481  struct fuse_bufvec mem_buf = FUSE_BUFVEC_INIT(len);
482  void *mbuf;
483  int res;
484 
485  /* Optimize common case */
486  if (buf->count == 1 && buf->idx == 0 && buf->off == 0 &&
487  !(buf->buf[0].flags & FUSE_BUF_IS_FD)) {
488  /* FIXME: also avoid memory copy if there are multiple buffers
489  but none of them contain an fd */
490 
491  iov[iov_count].iov_base = buf->buf[0].mem;
492  iov[iov_count].iov_len = len;
493  iov_count++;
494  return fuse_send_msg(se, ch, iov, iov_count);
495  }
496 
497  res = posix_memalign(&mbuf, pagesize, len);
498  if (res != 0)
499  return res;
500 
501  mem_buf.buf[0].mem = mbuf;
502  res = fuse_buf_copy(&mem_buf, buf, 0);
503  if (res < 0) {
504  free(mbuf);
505  return -res;
506  }
507  len = res;
508 
509  iov[iov_count].iov_base = mbuf;
510  iov[iov_count].iov_len = len;
511  iov_count++;
512  res = fuse_send_msg(se, ch, iov, iov_count);
513  free(mbuf);
514 
515  return res;
516 }
517 
518 struct fuse_ll_pipe {
519  size_t size;
520  int can_grow;
521  int pipe[2];
522 };
523 
524 static void fuse_ll_pipe_free(struct fuse_ll_pipe *llp)
525 {
526  close(llp->pipe[0]);
527  close(llp->pipe[1]);
528  free(llp);
529 }
530 
531 #ifdef HAVE_SPLICE
532 #if !defined(HAVE_PIPE2) || !defined(O_CLOEXEC)
533 static int fuse_pipe(int fds[2])
534 {
535  int rv = pipe(fds);
536 
537  if (rv == -1)
538  return rv;
539 
540  if (fcntl(fds[0], F_SETFL, O_NONBLOCK) == -1 ||
541  fcntl(fds[1], F_SETFL, O_NONBLOCK) == -1 ||
542  fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 ||
543  fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) {
544  close(fds[0]);
545  close(fds[1]);
546  rv = -1;
547  }
548  return rv;
549 }
550 #else
551 static int fuse_pipe(int fds[2])
552 {
553  return pipe2(fds, O_CLOEXEC | O_NONBLOCK);
554 }
555 #endif
556 
557 static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_session *se)
558 {
559  struct fuse_ll_pipe *llp = pthread_getspecific(se->pipe_key);
560  if (llp == NULL) {
561  int res;
562 
563  llp = malloc(sizeof(struct fuse_ll_pipe));
564  if (llp == NULL)
565  return NULL;
566 
567  res = fuse_pipe(llp->pipe);
568  if (res == -1) {
569  free(llp);
570  return NULL;
571  }
572 
573  /*
574  *the default size is 16 pages on linux
575  */
576  llp->size = pagesize * 16;
577  llp->can_grow = 1;
578 
579  pthread_setspecific(se->pipe_key, llp);
580  }
581 
582  return llp;
583 }
584 #endif
585 
586 static void fuse_ll_clear_pipe(struct fuse_session *se)
587 {
588  struct fuse_ll_pipe *llp = pthread_getspecific(se->pipe_key);
589  if (llp) {
590  pthread_setspecific(se->pipe_key, NULL);
591  fuse_ll_pipe_free(llp);
592  }
593 }
594 
595 #if defined(HAVE_SPLICE) && defined(HAVE_VMSPLICE)
596 static int read_back(int fd, char *buf, size_t len)
597 {
598  int res;
599 
600  res = read(fd, buf, len);
601  if (res == -1) {
602  fprintf(stderr, "fuse: internal error: failed to read back from pipe: %s\n", strerror(errno));
603  return -EIO;
604  }
605  if (res != len) {
606  fprintf(stderr, "fuse: internal error: short read back from pipe: %i from %zi\n", res, len);
607  return -EIO;
608  }
609  return 0;
610 }
611 
612 static int fuse_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
613  struct iovec *iov, int iov_count,
614  struct fuse_bufvec *buf, unsigned int flags)
615 {
616  int res;
617  size_t len = fuse_buf_size(buf);
618  struct fuse_out_header *out = iov[0].iov_base;
619  struct fuse_ll_pipe *llp;
620  int splice_flags;
621  size_t pipesize;
622  size_t total_fd_size;
623  size_t idx;
624  size_t headerlen;
625  struct fuse_bufvec pipe_buf = FUSE_BUFVEC_INIT(len);
626 
627  if (se->broken_splice_nonblock)
628  goto fallback;
629 
630  if (flags & FUSE_BUF_NO_SPLICE)
631  goto fallback;
632 
633  total_fd_size = 0;
634  for (idx = buf->idx; idx < buf->count; idx++) {
635  if (buf->buf[idx].flags & FUSE_BUF_IS_FD) {
636  total_fd_size = buf->buf[idx].size;
637  if (idx == buf->idx)
638  total_fd_size -= buf->off;
639  }
640  }
641  if (total_fd_size < 2 * pagesize)
642  goto fallback;
643 
644  if (se->conn.proto_minor < 14 ||
645  !(se->conn.want & FUSE_CAP_SPLICE_WRITE))
646  goto fallback;
647 
648  llp = fuse_ll_get_pipe(se);
649  if (llp == NULL)
650  goto fallback;
651 
652 
653  headerlen = iov_length(iov, iov_count);
654 
655  out->len = headerlen + len;
656 
657  /*
658  * Heuristic for the required pipe size, does not work if the
659  * source contains less than page size fragments
660  */
661  pipesize = pagesize * (iov_count + buf->count + 1) + out->len;
662 
663  if (llp->size < pipesize) {
664  if (llp->can_grow) {
665  res = fcntl(llp->pipe[0], F_SETPIPE_SZ, pipesize);
666  if (res == -1) {
667  llp->can_grow = 0;
668  goto fallback;
669  }
670  llp->size = res;
671  }
672  if (llp->size < pipesize)
673  goto fallback;
674  }
675 
676 
677  res = vmsplice(llp->pipe[1], iov, iov_count, SPLICE_F_NONBLOCK);
678  if (res == -1)
679  goto fallback;
680 
681  if (res != headerlen) {
682  res = -EIO;
683  fprintf(stderr, "fuse: short vmsplice to pipe: %u/%zu\n", res,
684  headerlen);
685  goto clear_pipe;
686  }
687 
688  pipe_buf.buf[0].flags = FUSE_BUF_IS_FD;
689  pipe_buf.buf[0].fd = llp->pipe[1];
690 
691  res = fuse_buf_copy(&pipe_buf, buf,
693  if (res < 0) {
694  if (res == -EAGAIN || res == -EINVAL) {
695  /*
696  * Should only get EAGAIN on kernels with
697  * broken SPLICE_F_NONBLOCK support (<=
698  * 2.6.35) where this error or a short read is
699  * returned even if the pipe itself is not
700  * full
701  *
702  * EINVAL might mean that splice can't handle
703  * this combination of input and output.
704  */
705  if (res == -EAGAIN)
706  se->broken_splice_nonblock = 1;
707 
708  pthread_setspecific(se->pipe_key, NULL);
709  fuse_ll_pipe_free(llp);
710  goto fallback;
711  }
712  res = -res;
713  goto clear_pipe;
714  }
715 
716  if (res != 0 && res < len) {
717  struct fuse_bufvec mem_buf = FUSE_BUFVEC_INIT(len);
718  void *mbuf;
719  size_t now_len = res;
720  /*
721  * For regular files a short count is either
722  * 1) due to EOF, or
723  * 2) because of broken SPLICE_F_NONBLOCK (see above)
724  *
725  * For other inputs it's possible that we overflowed
726  * the pipe because of small buffer fragments.
727  */
728 
729  res = posix_memalign(&mbuf, pagesize, len);
730  if (res != 0)
731  goto clear_pipe;
732 
733  mem_buf.buf[0].mem = mbuf;
734  mem_buf.off = now_len;
735  res = fuse_buf_copy(&mem_buf, buf, 0);
736  if (res > 0) {
737  char *tmpbuf;
738  size_t extra_len = res;
739  /*
740  * Trickiest case: got more data. Need to get
741  * back the data from the pipe and then fall
742  * back to regular write.
743  */
744  tmpbuf = malloc(headerlen);
745  if (tmpbuf == NULL) {
746  free(mbuf);
747  res = ENOMEM;
748  goto clear_pipe;
749  }
750  res = read_back(llp->pipe[0], tmpbuf, headerlen);
751  free(tmpbuf);
752  if (res != 0) {
753  free(mbuf);
754  goto clear_pipe;
755  }
756  res = read_back(llp->pipe[0], mbuf, now_len);
757  if (res != 0) {
758  free(mbuf);
759  goto clear_pipe;
760  }
761  len = now_len + extra_len;
762  iov[iov_count].iov_base = mbuf;
763  iov[iov_count].iov_len = len;
764  iov_count++;
765  res = fuse_send_msg(se, ch, iov, iov_count);
766  free(mbuf);
767  return res;
768  }
769  free(mbuf);
770  res = now_len;
771  }
772  len = res;
773  out->len = headerlen + len;
774 
775  if (se->debug) {
776  fprintf(stderr,
777  " unique: %llu, success, outsize: %i (splice)\n",
778  (unsigned long long) out->unique, out->len);
779  }
780 
781  splice_flags = 0;
782  if ((flags & FUSE_BUF_SPLICE_MOVE) &&
783  (se->conn.want & FUSE_CAP_SPLICE_MOVE))
784  splice_flags |= SPLICE_F_MOVE;
785 
786  res = splice(llp->pipe[0], NULL, ch ? ch->fd : se->fd,
787  NULL, out->len, splice_flags);
788  if (res == -1) {
789  res = -errno;
790  perror("fuse: splice from pipe");
791  goto clear_pipe;
792  }
793  if (res != out->len) {
794  res = -EIO;
795  fprintf(stderr, "fuse: short splice from pipe: %u/%u\n",
796  res, out->len);
797  goto clear_pipe;
798  }
799  return 0;
800 
801 clear_pipe:
802  fuse_ll_clear_pipe(se);
803  return res;
804 
805 fallback:
806  return fuse_send_data_iov_fallback(se, ch, iov, iov_count, buf, len);
807 }
808 #else
809 static int fuse_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
810  struct iovec *iov, int iov_count,
811  struct fuse_bufvec *buf, unsigned int flags)
812 {
813  size_t len = fuse_buf_size(buf);
814  (void) flags;
815 
816  return fuse_send_data_iov_fallback(se, ch, iov, iov_count, buf, len);
817 }
818 #endif
819 
820 int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv,
821  enum fuse_buf_copy_flags flags)
822 {
823  struct iovec iov[2];
824  struct fuse_out_header out;
825  int res;
826 
827  iov[0].iov_base = &out;
828  iov[0].iov_len = sizeof(struct fuse_out_header);
829 
830  out.unique = req->unique;
831  out.error = 0;
832 
833  res = fuse_send_data_iov(req->se, req->ch, iov, 1, bufv, flags);
834  if (res <= 0) {
835  fuse_free_req(req);
836  return res;
837  } else {
838  return fuse_reply_err(req, res);
839  }
840 }
841 
842 int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
843 {
844  struct fuse_statfs_out arg;
845  size_t size = req->se->conn.proto_minor < 4 ?
846  FUSE_COMPAT_STATFS_SIZE : sizeof(arg);
847 
848  memset(&arg, 0, sizeof(arg));
849  convert_statfs(stbuf, &arg.st);
850 
851  return send_reply_ok(req, &arg, size);
852 }
853 
854 int fuse_reply_xattr(fuse_req_t req, size_t count)
855 {
856  struct fuse_getxattr_out arg;
857 
858  memset(&arg, 0, sizeof(arg));
859  arg.size = count;
860 
861  return send_reply_ok(req, &arg, sizeof(arg));
862 }
863 
864 int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
865 {
866  struct fuse_lk_out arg;
867 
868  memset(&arg, 0, sizeof(arg));
869  arg.lk.type = lock->l_type;
870  if (lock->l_type != F_UNLCK) {
871  arg.lk.start = lock->l_start;
872  if (lock->l_len == 0)
873  arg.lk.end = OFFSET_MAX;
874  else
875  arg.lk.end = lock->l_start + lock->l_len - 1;
876  }
877  arg.lk.pid = lock->l_pid;
878  return send_reply_ok(req, &arg, sizeof(arg));
879 }
880 
881 int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
882 {
883  struct fuse_bmap_out arg;
884 
885  memset(&arg, 0, sizeof(arg));
886  arg.block = idx;
887 
888  return send_reply_ok(req, &arg, sizeof(arg));
889 }
890 
891 static struct fuse_ioctl_iovec *fuse_ioctl_iovec_copy(const struct iovec *iov,
892  size_t count)
893 {
894  struct fuse_ioctl_iovec *fiov;
895  size_t i;
896 
897  fiov = malloc(sizeof(fiov[0]) * count);
898  if (!fiov)
899  return NULL;
900 
901  for (i = 0; i < count; i++) {
902  fiov[i].base = (uintptr_t) iov[i].iov_base;
903  fiov[i].len = iov[i].iov_len;
904  }
905 
906  return fiov;
907 }
908 
910  const struct iovec *in_iov, size_t in_count,
911  const struct iovec *out_iov, size_t out_count)
912 {
913  struct fuse_ioctl_out arg;
914  struct fuse_ioctl_iovec *in_fiov = NULL;
915  struct fuse_ioctl_iovec *out_fiov = NULL;
916  struct iovec iov[4];
917  size_t count = 1;
918  int res;
919 
920  memset(&arg, 0, sizeof(arg));
921  arg.flags |= FUSE_IOCTL_RETRY;
922  arg.in_iovs = in_count;
923  arg.out_iovs = out_count;
924  iov[count].iov_base = &arg;
925  iov[count].iov_len = sizeof(arg);
926  count++;
927 
928  if (req->se->conn.proto_minor < 16) {
929  if (in_count) {
930  iov[count].iov_base = (void *)in_iov;
931  iov[count].iov_len = sizeof(in_iov[0]) * in_count;
932  count++;
933  }
934 
935  if (out_count) {
936  iov[count].iov_base = (void *)out_iov;
937  iov[count].iov_len = sizeof(out_iov[0]) * out_count;
938  count++;
939  }
940  } else {
941  /* Can't handle non-compat 64bit ioctls on 32bit */
942  if (sizeof(void *) == 4 && req->ioctl_64bit) {
943  res = fuse_reply_err(req, EINVAL);
944  goto out;
945  }
946 
947  if (in_count) {
948  in_fiov = fuse_ioctl_iovec_copy(in_iov, in_count);
949  if (!in_fiov)
950  goto enomem;
951 
952  iov[count].iov_base = (void *)in_fiov;
953  iov[count].iov_len = sizeof(in_fiov[0]) * in_count;
954  count++;
955  }
956  if (out_count) {
957  out_fiov = fuse_ioctl_iovec_copy(out_iov, out_count);
958  if (!out_fiov)
959  goto enomem;
960 
961  iov[count].iov_base = (void *)out_fiov;
962  iov[count].iov_len = sizeof(out_fiov[0]) * out_count;
963  count++;
964  }
965  }
966 
967  res = send_reply_iov(req, 0, iov, count);
968 out:
969  free(in_fiov);
970  free(out_fiov);
971 
972  return res;
973 
974 enomem:
975  res = fuse_reply_err(req, ENOMEM);
976  goto out;
977 }
978 
979 int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
980 {
981  struct fuse_ioctl_out arg;
982  struct iovec iov[3];
983  size_t count = 1;
984 
985  memset(&arg, 0, sizeof(arg));
986  arg.result = result;
987  iov[count].iov_base = &arg;
988  iov[count].iov_len = sizeof(arg);
989  count++;
990 
991  if (size) {
992  iov[count].iov_base = (char *) buf;
993  iov[count].iov_len = size;
994  count++;
995  }
996 
997  return send_reply_iov(req, 0, iov, count);
998 }
999 
1000 int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov,
1001  int count)
1002 {
1003  struct iovec *padded_iov;
1004  struct fuse_ioctl_out arg;
1005  int res;
1006 
1007  padded_iov = malloc((count + 2) * sizeof(struct iovec));
1008  if (padded_iov == NULL)
1009  return fuse_reply_err(req, ENOMEM);
1010 
1011  memset(&arg, 0, sizeof(arg));
1012  arg.result = result;
1013  padded_iov[1].iov_base = &arg;
1014  padded_iov[1].iov_len = sizeof(arg);
1015 
1016  memcpy(&padded_iov[2], iov, count * sizeof(struct iovec));
1017 
1018  res = send_reply_iov(req, 0, padded_iov, count + 2);
1019  free(padded_iov);
1020 
1021  return res;
1022 }
1023 
1024 int fuse_reply_poll(fuse_req_t req, unsigned revents)
1025 {
1026  struct fuse_poll_out arg;
1027 
1028  memset(&arg, 0, sizeof(arg));
1029  arg.revents = revents;
1030 
1031  return send_reply_ok(req, &arg, sizeof(arg));
1032 }
1033 
1034 static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1035 {
1036  char *name = (char *) inarg;
1037 
1038  if (req->se->op.lookup)
1039  req->se->op.lookup(req, nodeid, name);
1040  else
1041  fuse_reply_err(req, ENOSYS);
1042 }
1043 
1044 static void do_forget(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1045 {
1046  struct fuse_forget_in *arg = (struct fuse_forget_in *) inarg;
1047 
1048  if (req->se->op.forget)
1049  req->se->op.forget(req, nodeid, arg->nlookup);
1050  else
1051  fuse_reply_none(req);
1052 }
1053 
1054 static void do_batch_forget(fuse_req_t req, fuse_ino_t nodeid,
1055  const void *inarg)
1056 {
1057  struct fuse_batch_forget_in *arg = (void *) inarg;
1058  struct fuse_forget_one *param = (void *) PARAM(arg);
1059  unsigned int i;
1060 
1061  (void) nodeid;
1062 
1063  if (req->se->op.forget_multi) {
1064  req->se->op.forget_multi(req, arg->count,
1065  (struct fuse_forget_data *) param);
1066  } else if (req->se->op.forget) {
1067  for (i = 0; i < arg->count; i++) {
1068  struct fuse_forget_one *forget = &param[i];
1069  struct fuse_req *dummy_req;
1070 
1071  dummy_req = fuse_ll_alloc_req(req->se);
1072  if (dummy_req == NULL)
1073  break;
1074 
1075  dummy_req->unique = req->unique;
1076  dummy_req->ctx = req->ctx;
1077  dummy_req->ch = NULL;
1078 
1079  req->se->op.forget(dummy_req, forget->nodeid,
1080  forget->nlookup);
1081  }
1082  fuse_reply_none(req);
1083  } else {
1084  fuse_reply_none(req);
1085  }
1086 }
1087 
1088 static void do_getattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1089 {
1090  struct fuse_file_info *fip = NULL;
1091  struct fuse_file_info fi;
1092 
1093  if (req->se->conn.proto_minor >= 9) {
1094  struct fuse_getattr_in *arg = (struct fuse_getattr_in *) inarg;
1095 
1096  if (arg->getattr_flags & FUSE_GETATTR_FH) {
1097  memset(&fi, 0, sizeof(fi));
1098  fi.fh = arg->fh;
1099  fip = &fi;
1100  }
1101  }
1102 
1103  if (req->se->op.getattr)
1104  req->se->op.getattr(req, nodeid, fip);
1105  else
1106  fuse_reply_err(req, ENOSYS);
1107 }
1108 
1109 static void do_setattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1110 {
1111  struct fuse_setattr_in *arg = (struct fuse_setattr_in *) inarg;
1112 
1113  if (req->se->op.setattr) {
1114  struct fuse_file_info *fi = NULL;
1115  struct fuse_file_info fi_store;
1116  struct stat stbuf;
1117  memset(&stbuf, 0, sizeof(stbuf));
1118  convert_attr(arg, &stbuf);
1119  if (arg->valid & FATTR_FH) {
1120  arg->valid &= ~FATTR_FH;
1121  memset(&fi_store, 0, sizeof(fi_store));
1122  fi = &fi_store;
1123  fi->fh = arg->fh;
1124  }
1125  arg->valid &=
1126  FUSE_SET_ATTR_MODE |
1127  FUSE_SET_ATTR_UID |
1128  FUSE_SET_ATTR_GID |
1129  FUSE_SET_ATTR_SIZE |
1130  FUSE_SET_ATTR_ATIME |
1131  FUSE_SET_ATTR_MTIME |
1132  FUSE_SET_ATTR_ATIME_NOW |
1133  FUSE_SET_ATTR_MTIME_NOW |
1134  FUSE_SET_ATTR_CTIME;
1135 
1136  req->se->op.setattr(req, nodeid, &stbuf, arg->valid, fi);
1137  } else
1138  fuse_reply_err(req, ENOSYS);
1139 }
1140 
1141 static void do_access(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1142 {
1143  struct fuse_access_in *arg = (struct fuse_access_in *) inarg;
1144 
1145  if (req->se->op.access)
1146  req->se->op.access(req, nodeid, arg->mask);
1147  else
1148  fuse_reply_err(req, ENOSYS);
1149 }
1150 
1151 static void do_readlink(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1152 {
1153  (void) inarg;
1154 
1155  if (req->se->op.readlink)
1156  req->se->op.readlink(req, nodeid);
1157  else
1158  fuse_reply_err(req, ENOSYS);
1159 }
1160 
1161 static void do_mknod(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1162 {
1163  struct fuse_mknod_in *arg = (struct fuse_mknod_in *) inarg;
1164  char *name = PARAM(arg);
1165 
1166  if (req->se->conn.proto_minor >= 12)
1167  req->ctx.umask = arg->umask;
1168  else
1169  name = (char *) inarg + FUSE_COMPAT_MKNOD_IN_SIZE;
1170 
1171  if (req->se->op.mknod)
1172  req->se->op.mknod(req, nodeid, name, arg->mode, arg->rdev);
1173  else
1174  fuse_reply_err(req, ENOSYS);
1175 }
1176 
1177 static void do_mkdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1178 {
1179  struct fuse_mkdir_in *arg = (struct fuse_mkdir_in *) inarg;
1180 
1181  if (req->se->conn.proto_minor >= 12)
1182  req->ctx.umask = arg->umask;
1183 
1184  if (req->se->op.mkdir)
1185  req->se->op.mkdir(req, nodeid, PARAM(arg), arg->mode);
1186  else
1187  fuse_reply_err(req, ENOSYS);
1188 }
1189 
1190 static void do_unlink(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1191 {
1192  char *name = (char *) inarg;
1193 
1194  if (req->se->op.unlink)
1195  req->se->op.unlink(req, nodeid, name);
1196  else
1197  fuse_reply_err(req, ENOSYS);
1198 }
1199 
1200 static void do_rmdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1201 {
1202  char *name = (char *) inarg;
1203 
1204  if (req->se->op.rmdir)
1205  req->se->op.rmdir(req, nodeid, name);
1206  else
1207  fuse_reply_err(req, ENOSYS);
1208 }
1209 
1210 static void do_symlink(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1211 {
1212  char *name = (char *) inarg;
1213  char *linkname = ((char *) inarg) + strlen((char *) inarg) + 1;
1214 
1215  if (req->se->op.symlink)
1216  req->se->op.symlink(req, linkname, nodeid, name);
1217  else
1218  fuse_reply_err(req, ENOSYS);
1219 }
1220 
1221 static void do_rename(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1222 {
1223  struct fuse_rename_in *arg = (struct fuse_rename_in *) inarg;
1224  char *oldname = PARAM(arg);
1225  char *newname = oldname + strlen(oldname) + 1;
1226 
1227  if (req->se->op.rename)
1228  req->se->op.rename(req, nodeid, oldname, arg->newdir, newname,
1229  0);
1230  else
1231  fuse_reply_err(req, ENOSYS);
1232 }
1233 
1234 static void do_rename2(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1235 {
1236  struct fuse_rename2_in *arg = (struct fuse_rename2_in *) inarg;
1237  char *oldname = PARAM(arg);
1238  char *newname = oldname + strlen(oldname) + 1;
1239 
1240  if (req->se->op.rename)
1241  req->se->op.rename(req, nodeid, oldname, arg->newdir, newname,
1242  arg->flags);
1243  else
1244  fuse_reply_err(req, ENOSYS);
1245 }
1246 
1247 static void do_link(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1248 {
1249  struct fuse_link_in *arg = (struct fuse_link_in *) inarg;
1250 
1251  if (req->se->op.link)
1252  req->se->op.link(req, arg->oldnodeid, nodeid, PARAM(arg));
1253  else
1254  fuse_reply_err(req, ENOSYS);
1255 }
1256 
1257 static void do_create(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1258 {
1259  struct fuse_create_in *arg = (struct fuse_create_in *) inarg;
1260 
1261  if (req->se->op.create) {
1262  struct fuse_file_info fi;
1263  char *name = PARAM(arg);
1264 
1265  memset(&fi, 0, sizeof(fi));
1266  fi.flags = arg->flags;
1267 
1268  if (req->se->conn.proto_minor >= 12)
1269  req->ctx.umask = arg->umask;
1270  else
1271  name = (char *) inarg + sizeof(struct fuse_open_in);
1272 
1273  req->se->op.create(req, nodeid, name, arg->mode, &fi);
1274  } else
1275  fuse_reply_err(req, ENOSYS);
1276 }
1277 
1278 static void do_open(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1279 {
1280  struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
1281  struct fuse_file_info fi;
1282 
1283  memset(&fi, 0, sizeof(fi));
1284  fi.flags = arg->flags;
1285 
1286  if (req->se->op.open)
1287  req->se->op.open(req, nodeid, &fi);
1288  else
1289  fuse_reply_open(req, &fi);
1290 }
1291 
1292 static void do_read(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1293 {
1294  struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
1295 
1296  if (req->se->op.read) {
1297  struct fuse_file_info fi;
1298 
1299  memset(&fi, 0, sizeof(fi));
1300  fi.fh = arg->fh;
1301  if (req->se->conn.proto_minor >= 9) {
1302  fi.lock_owner = arg->lock_owner;
1303  fi.flags = arg->flags;
1304  }
1305  req->se->op.read(req, nodeid, arg->size, arg->offset, &fi);
1306  } else
1307  fuse_reply_err(req, ENOSYS);
1308 }
1309 
1310 static void do_write(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1311 {
1312  struct fuse_write_in *arg = (struct fuse_write_in *) inarg;
1313  struct fuse_file_info fi;
1314  char *param;
1315 
1316  memset(&fi, 0, sizeof(fi));
1317  fi.fh = arg->fh;
1318  fi.writepage = (arg->write_flags & 1) != 0;
1319 
1320  if (req->se->conn.proto_minor < 9) {
1321  param = ((char *) arg) + FUSE_COMPAT_WRITE_IN_SIZE;
1322  } else {
1323  fi.lock_owner = arg->lock_owner;
1324  fi.flags = arg->flags;
1325  param = PARAM(arg);
1326  }
1327 
1328  if (req->se->op.write)
1329  req->se->op.write(req, nodeid, param, arg->size,
1330  arg->offset, &fi);
1331  else
1332  fuse_reply_err(req, ENOSYS);
1333 }
1334 
1335 static void do_write_buf(fuse_req_t req, fuse_ino_t nodeid, const void *inarg,
1336  const struct fuse_buf *ibuf)
1337 {
1338  struct fuse_session *se = req->se;
1339  struct fuse_bufvec bufv = {
1340  .buf[0] = *ibuf,
1341  .count = 1,
1342  };
1343  struct fuse_write_in *arg = (struct fuse_write_in *) inarg;
1344  struct fuse_file_info fi;
1345 
1346  memset(&fi, 0, sizeof(fi));
1347  fi.fh = arg->fh;
1348  fi.writepage = arg->write_flags & 1;
1349 
1350  if (se->conn.proto_minor < 9) {
1351  bufv.buf[0].mem = ((char *) arg) + FUSE_COMPAT_WRITE_IN_SIZE;
1352  bufv.buf[0].size -= sizeof(struct fuse_in_header) +
1353  FUSE_COMPAT_WRITE_IN_SIZE;
1354  assert(!(bufv.buf[0].flags & FUSE_BUF_IS_FD));
1355  } else {
1356  fi.lock_owner = arg->lock_owner;
1357  fi.flags = arg->flags;
1358  if (!(bufv.buf[0].flags & FUSE_BUF_IS_FD))
1359  bufv.buf[0].mem = PARAM(arg);
1360 
1361  bufv.buf[0].size -= sizeof(struct fuse_in_header) +
1362  sizeof(struct fuse_write_in);
1363  }
1364  if (bufv.buf[0].size < arg->size) {
1365  fprintf(stderr, "fuse: do_write_buf: buffer size too small\n");
1366  fuse_reply_err(req, EIO);
1367  goto out;
1368  }
1369  bufv.buf[0].size = arg->size;
1370 
1371  se->op.write_buf(req, nodeid, &bufv, arg->offset, &fi);
1372 
1373 out:
1374  /* Need to reset the pipe if ->write_buf() didn't consume all data */
1375  if ((ibuf->flags & FUSE_BUF_IS_FD) && bufv.idx < bufv.count)
1376  fuse_ll_clear_pipe(se);
1377 }
1378 
1379 static void do_flush(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1380 {
1381  struct fuse_flush_in *arg = (struct fuse_flush_in *) inarg;
1382  struct fuse_file_info fi;
1383 
1384  memset(&fi, 0, sizeof(fi));
1385  fi.fh = arg->fh;
1386  fi.flush = 1;
1387  if (req->se->conn.proto_minor >= 7)
1388  fi.lock_owner = arg->lock_owner;
1389 
1390  if (req->se->op.flush)
1391  req->se->op.flush(req, nodeid, &fi);
1392  else
1393  fuse_reply_err(req, ENOSYS);
1394 }
1395 
1396 static void do_release(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1397 {
1398  struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
1399  struct fuse_file_info fi;
1400 
1401  memset(&fi, 0, sizeof(fi));
1402  fi.flags = arg->flags;
1403  fi.fh = arg->fh;
1404  if (req->se->conn.proto_minor >= 8) {
1405  fi.flush = (arg->release_flags & FUSE_RELEASE_FLUSH) ? 1 : 0;
1406  fi.lock_owner = arg->lock_owner;
1407  }
1408  if (arg->release_flags & FUSE_RELEASE_FLOCK_UNLOCK) {
1409  fi.flock_release = 1;
1410  fi.lock_owner = arg->lock_owner;
1411  }
1412 
1413  if (req->se->op.release)
1414  req->se->op.release(req, nodeid, &fi);
1415  else
1416  fuse_reply_err(req, 0);
1417 }
1418 
1419 static void do_fsync(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1420 {
1421  struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
1422  struct fuse_file_info fi;
1423 
1424  memset(&fi, 0, sizeof(fi));
1425  fi.fh = arg->fh;
1426 
1427  if (req->se->op.fsync)
1428  req->se->op.fsync(req, nodeid, arg->fsync_flags & 1, &fi);
1429  else
1430  fuse_reply_err(req, ENOSYS);
1431 }
1432 
1433 static void do_opendir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1434 {
1435  struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
1436  struct fuse_file_info fi;
1437 
1438  memset(&fi, 0, sizeof(fi));
1439  fi.flags = arg->flags;
1440 
1441  if (req->se->op.opendir)
1442  req->se->op.opendir(req, nodeid, &fi);
1443  else
1444  fuse_reply_open(req, &fi);
1445 }
1446 
1447 static void do_readdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1448 {
1449  struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
1450  struct fuse_file_info fi;
1451 
1452  memset(&fi, 0, sizeof(fi));
1453  fi.fh = arg->fh;
1454 
1455  if (req->se->op.readdir)
1456  req->se->op.readdir(req, nodeid, arg->size, arg->offset, &fi);
1457  else
1458  fuse_reply_err(req, ENOSYS);
1459 }
1460 
1461 static void do_readdirplus(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1462 {
1463  struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
1464  struct fuse_file_info fi;
1465 
1466  memset(&fi, 0, sizeof(fi));
1467  fi.fh = arg->fh;
1468 
1469  if (req->se->op.readdirplus)
1470  req->se->op.readdirplus(req, nodeid, arg->size, arg->offset, &fi);
1471  else
1472  fuse_reply_err(req, ENOSYS);
1473 }
1474 
1475 static void do_releasedir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1476 {
1477  struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
1478  struct fuse_file_info fi;
1479 
1480  memset(&fi, 0, sizeof(fi));
1481  fi.flags = arg->flags;
1482  fi.fh = arg->fh;
1483 
1484  if (req->se->op.releasedir)
1485  req->se->op.releasedir(req, nodeid, &fi);
1486  else
1487  fuse_reply_err(req, 0);
1488 }
1489 
1490 static void do_fsyncdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1491 {
1492  struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
1493  struct fuse_file_info fi;
1494 
1495  memset(&fi, 0, sizeof(fi));
1496  fi.fh = arg->fh;
1497 
1498  if (req->se->op.fsyncdir)
1499  req->se->op.fsyncdir(req, nodeid, arg->fsync_flags & 1, &fi);
1500  else
1501  fuse_reply_err(req, ENOSYS);
1502 }
1503 
1504 static void do_statfs(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1505 {
1506  (void) nodeid;
1507  (void) inarg;
1508 
1509  if (req->se->op.statfs)
1510  req->se->op.statfs(req, nodeid);
1511  else {
1512  struct statvfs buf = {
1513  .f_namemax = 255,
1514  .f_bsize = 512,
1515  };
1516  fuse_reply_statfs(req, &buf);
1517  }
1518 }
1519 
1520 static void do_setxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1521 {
1522  struct fuse_setxattr_in *arg = (struct fuse_setxattr_in *) inarg;
1523  char *name = PARAM(arg);
1524  char *value = name + strlen(name) + 1;
1525 
1526  if (req->se->op.setxattr)
1527  req->se->op.setxattr(req, nodeid, name, value, arg->size,
1528  arg->flags);
1529  else
1530  fuse_reply_err(req, ENOSYS);
1531 }
1532 
1533 static void do_getxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1534 {
1535  struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
1536 
1537  if (req->se->op.getxattr)
1538  req->se->op.getxattr(req, nodeid, PARAM(arg), arg->size);
1539  else
1540  fuse_reply_err(req, ENOSYS);
1541 }
1542 
1543 static void do_listxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1544 {
1545  struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
1546 
1547  if (req->se->op.listxattr)
1548  req->se->op.listxattr(req, nodeid, arg->size);
1549  else
1550  fuse_reply_err(req, ENOSYS);
1551 }
1552 
1553 static void do_removexattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1554 {
1555  char *name = (char *) inarg;
1556 
1557  if (req->se->op.removexattr)
1558  req->se->op.removexattr(req, nodeid, name);
1559  else
1560  fuse_reply_err(req, ENOSYS);
1561 }
1562 
1563 static void convert_fuse_file_lock(struct fuse_file_lock *fl,
1564  struct flock *flock)
1565 {
1566  memset(flock, 0, sizeof(struct flock));
1567  flock->l_type = fl->type;
1568  flock->l_whence = SEEK_SET;
1569  flock->l_start = fl->start;
1570  if (fl->end == OFFSET_MAX)
1571  flock->l_len = 0;
1572  else
1573  flock->l_len = fl->end - fl->start + 1;
1574  flock->l_pid = fl->pid;
1575 }
1576 
1577 static void do_getlk(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1578 {
1579  struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
1580  struct fuse_file_info fi;
1581  struct flock flock;
1582 
1583  memset(&fi, 0, sizeof(fi));
1584  fi.fh = arg->fh;
1585  fi.lock_owner = arg->owner;
1586 
1587  convert_fuse_file_lock(&arg->lk, &flock);
1588  if (req->se->op.getlk)
1589  req->se->op.getlk(req, nodeid, &fi, &flock);
1590  else
1591  fuse_reply_err(req, ENOSYS);
1592 }
1593 
1594 static void do_setlk_common(fuse_req_t req, fuse_ino_t nodeid,
1595  const void *inarg, int sleep)
1596 {
1597  struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
1598  struct fuse_file_info fi;
1599  struct flock flock;
1600 
1601  memset(&fi, 0, sizeof(fi));
1602  fi.fh = arg->fh;
1603  fi.lock_owner = arg->owner;
1604 
1605  if (arg->lk_flags & FUSE_LK_FLOCK) {
1606  int op = 0;
1607 
1608  switch (arg->lk.type) {
1609  case F_RDLCK:
1610  op = LOCK_SH;
1611  break;
1612  case F_WRLCK:
1613  op = LOCK_EX;
1614  break;
1615  case F_UNLCK:
1616  op = LOCK_UN;
1617  break;
1618  }
1619  if (!sleep)
1620  op |= LOCK_NB;
1621 
1622  if (req->se->op.flock)
1623  req->se->op.flock(req, nodeid, &fi, op);
1624  else
1625  fuse_reply_err(req, ENOSYS);
1626  } else {
1627  convert_fuse_file_lock(&arg->lk, &flock);
1628  if (req->se->op.setlk)
1629  req->se->op.setlk(req, nodeid, &fi, &flock, sleep);
1630  else
1631  fuse_reply_err(req, ENOSYS);
1632  }
1633 }
1634 
1635 static void do_setlk(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1636 {
1637  do_setlk_common(req, nodeid, inarg, 0);
1638 }
1639 
1640 static void do_setlkw(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1641 {
1642  do_setlk_common(req, nodeid, inarg, 1);
1643 }
1644 
1645 static int find_interrupted(struct fuse_session *se, struct fuse_req *req)
1646 {
1647  struct fuse_req *curr;
1648 
1649  for (curr = se->list.next; curr != &se->list; curr = curr->next) {
1650  if (curr->unique == req->u.i.unique) {
1651  fuse_interrupt_func_t func;
1652  void *data;
1653 
1654  curr->ctr++;
1655  pthread_mutex_unlock(&se->lock);
1656 
1657  /* Ugh, ugly locking */
1658  pthread_mutex_lock(&curr->lock);
1659  pthread_mutex_lock(&se->lock);
1660  curr->interrupted = 1;
1661  func = curr->u.ni.func;
1662  data = curr->u.ni.data;
1663  pthread_mutex_unlock(&se->lock);
1664  if (func)
1665  func(curr, data);
1666  pthread_mutex_unlock(&curr->lock);
1667 
1668  pthread_mutex_lock(&se->lock);
1669  curr->ctr--;
1670  if (!curr->ctr)
1671  destroy_req(curr);
1672 
1673  return 1;
1674  }
1675  }
1676  for (curr = se->interrupts.next; curr != &se->interrupts;
1677  curr = curr->next) {
1678  if (curr->u.i.unique == req->u.i.unique)
1679  return 1;
1680  }
1681  return 0;
1682 }
1683 
1684 static void do_interrupt(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1685 {
1686  struct fuse_interrupt_in *arg = (struct fuse_interrupt_in *) inarg;
1687  struct fuse_session *se = req->se;
1688 
1689  (void) nodeid;
1690  if (se->debug)
1691  fprintf(stderr, "INTERRUPT: %llu\n",
1692  (unsigned long long) arg->unique);
1693 
1694  req->u.i.unique = arg->unique;
1695 
1696  pthread_mutex_lock(&se->lock);
1697  if (find_interrupted(se, req))
1698  destroy_req(req);
1699  else
1700  list_add_req(req, &se->interrupts);
1701  pthread_mutex_unlock(&se->lock);
1702 }
1703 
1704 static struct fuse_req *check_interrupt(struct fuse_session *se,
1705  struct fuse_req *req)
1706 {
1707  struct fuse_req *curr;
1708 
1709  for (curr = se->interrupts.next; curr != &se->interrupts;
1710  curr = curr->next) {
1711  if (curr->u.i.unique == req->unique) {
1712  req->interrupted = 1;
1713  list_del_req(curr);
1714  free(curr);
1715  return NULL;
1716  }
1717  }
1718  curr = se->interrupts.next;
1719  if (curr != &se->interrupts) {
1720  list_del_req(curr);
1721  list_init_req(curr);
1722  return curr;
1723  } else
1724  return NULL;
1725 }
1726 
1727 static void do_bmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1728 {
1729  struct fuse_bmap_in *arg = (struct fuse_bmap_in *) inarg;
1730 
1731  if (req->se->op.bmap)
1732  req->se->op.bmap(req, nodeid, arg->blocksize, arg->block);
1733  else
1734  fuse_reply_err(req, ENOSYS);
1735 }
1736 
1737 static void do_ioctl(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1738 {
1739  struct fuse_ioctl_in *arg = (struct fuse_ioctl_in *) inarg;
1740  unsigned int flags = arg->flags;
1741  void *in_buf = arg->in_size ? PARAM(arg) : NULL;
1742  struct fuse_file_info fi;
1743 
1744  if (flags & FUSE_IOCTL_DIR &&
1745  !(req->se->conn.want & FUSE_CAP_IOCTL_DIR)) {
1746  fuse_reply_err(req, ENOTTY);
1747  return;
1748  }
1749 
1750  memset(&fi, 0, sizeof(fi));
1751  fi.fh = arg->fh;
1752 
1753  if (sizeof(void *) == 4 && req->se->conn.proto_minor >= 16 &&
1754  !(flags & FUSE_IOCTL_32BIT)) {
1755  req->ioctl_64bit = 1;
1756  }
1757 
1758  if (req->se->op.ioctl)
1759  req->se->op.ioctl(req, nodeid, arg->cmd,
1760  (void *)(uintptr_t)arg->arg, &fi, flags,
1761  in_buf, arg->in_size, arg->out_size);
1762  else
1763  fuse_reply_err(req, ENOSYS);
1764 }
1765 
1766 void fuse_pollhandle_destroy(struct fuse_pollhandle *ph)
1767 {
1768  free(ph);
1769 }
1770 
1771 static void do_poll(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1772 {
1773  struct fuse_poll_in *arg = (struct fuse_poll_in *) inarg;
1774  struct fuse_file_info fi;
1775 
1776  memset(&fi, 0, sizeof(fi));
1777  fi.fh = arg->fh;
1778  fi.poll_events = arg->events;
1779 
1780  if (req->se->op.poll) {
1781  struct fuse_pollhandle *ph = NULL;
1782 
1783  if (arg->flags & FUSE_POLL_SCHEDULE_NOTIFY) {
1784  ph = malloc(sizeof(struct fuse_pollhandle));
1785  if (ph == NULL) {
1786  fuse_reply_err(req, ENOMEM);
1787  return;
1788  }
1789  ph->kh = arg->kh;
1790  ph->se = req->se;
1791  }
1792 
1793  req->se->op.poll(req, nodeid, &fi, ph);
1794  } else {
1795  fuse_reply_err(req, ENOSYS);
1796  }
1797 }
1798 
1799 static void do_fallocate(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1800 {
1801  struct fuse_fallocate_in *arg = (struct fuse_fallocate_in *) inarg;
1802  struct fuse_file_info fi;
1803 
1804  memset(&fi, 0, sizeof(fi));
1805  fi.fh = arg->fh;
1806 
1807  if (req->se->op.fallocate)
1808  req->se->op.fallocate(req, nodeid, arg->mode, arg->offset, arg->length, &fi);
1809  else
1810  fuse_reply_err(req, ENOSYS);
1811 }
1812 
1813 static void do_copy_file_range(fuse_req_t req, fuse_ino_t nodeid_in, const void *inarg)
1814 {
1815  struct fuse_copy_file_range_in *arg = (struct fuse_copy_file_range_in *) inarg;
1816  struct fuse_file_info fi_in, fi_out;
1817 
1818  memset(&fi_in, 0, sizeof(fi_in));
1819  fi_in.fh = arg->fh_in;
1820 
1821  memset(&fi_out, 0, sizeof(fi_out));
1822  fi_out.fh = arg->fh_out;
1823 
1824 
1825  if (req->se->op.copy_file_range)
1826  req->se->op.copy_file_range(req, nodeid_in, arg->off_in,
1827  &fi_in, arg->nodeid_out,
1828  arg->off_out, &fi_out, arg->len,
1829  arg->flags);
1830  else
1831  fuse_reply_err(req, ENOSYS);
1832 }
1833 
1834 static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
1835 {
1836  struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
1837  struct fuse_init_out outarg;
1838  struct fuse_session *se = req->se;
1839  size_t bufsize = se->bufsize;
1840  size_t outargsize = sizeof(outarg);
1841 
1842  (void) nodeid;
1843  if (se->debug) {
1844  fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor);
1845  if (arg->major == 7 && arg->minor >= 6) {
1846  fprintf(stderr, "flags=0x%08x\n", arg->flags);
1847  fprintf(stderr, "max_readahead=0x%08x\n",
1848  arg->max_readahead);
1849  }
1850  }
1851  se->conn.proto_major = arg->major;
1852  se->conn.proto_minor = arg->minor;
1853  se->conn.capable = 0;
1854  se->conn.want = 0;
1855 
1856  memset(&outarg, 0, sizeof(outarg));
1857  outarg.major = FUSE_KERNEL_VERSION;
1858  outarg.minor = FUSE_KERNEL_MINOR_VERSION;
1859 
1860  if (arg->major < 7) {
1861  fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n",
1862  arg->major, arg->minor);
1863  fuse_reply_err(req, EPROTO);
1864  return;
1865  }
1866 
1867  if (arg->major > 7) {
1868  /* Wait for a second INIT request with a 7.X version */
1869  send_reply_ok(req, &outarg, sizeof(outarg));
1870  return;
1871  }
1872 
1873  if (arg->minor >= 6) {
1874  if (arg->max_readahead < se->conn.max_readahead)
1875  se->conn.max_readahead = arg->max_readahead;
1876  if (arg->flags & FUSE_ASYNC_READ)
1877  se->conn.capable |= FUSE_CAP_ASYNC_READ;
1878  if (arg->flags & FUSE_POSIX_LOCKS)
1879  se->conn.capable |= FUSE_CAP_POSIX_LOCKS;
1880  if (arg->flags & FUSE_ATOMIC_O_TRUNC)
1881  se->conn.capable |= FUSE_CAP_ATOMIC_O_TRUNC;
1882  if (arg->flags & FUSE_EXPORT_SUPPORT)
1883  se->conn.capable |= FUSE_CAP_EXPORT_SUPPORT;
1884  if (arg->flags & FUSE_DONT_MASK)
1885  se->conn.capable |= FUSE_CAP_DONT_MASK;
1886  if (arg->flags & FUSE_FLOCK_LOCKS)
1887  se->conn.capable |= FUSE_CAP_FLOCK_LOCKS;
1888  if (arg->flags & FUSE_AUTO_INVAL_DATA)
1889  se->conn.capable |= FUSE_CAP_AUTO_INVAL_DATA;
1890  if (arg->flags & FUSE_DO_READDIRPLUS)
1891  se->conn.capable |= FUSE_CAP_READDIRPLUS;
1892  if (arg->flags & FUSE_READDIRPLUS_AUTO)
1893  se->conn.capable |= FUSE_CAP_READDIRPLUS_AUTO;
1894  if (arg->flags & FUSE_ASYNC_DIO)
1895  se->conn.capable |= FUSE_CAP_ASYNC_DIO;
1896  if (arg->flags & FUSE_WRITEBACK_CACHE)
1897  se->conn.capable |= FUSE_CAP_WRITEBACK_CACHE;
1898  if (arg->flags & FUSE_NO_OPEN_SUPPORT)
1899  se->conn.capable |= FUSE_CAP_NO_OPEN_SUPPORT;
1900  if (arg->flags & FUSE_PARALLEL_DIROPS)
1901  se->conn.capable |= FUSE_CAP_PARALLEL_DIROPS;
1902  if (arg->flags & FUSE_POSIX_ACL)
1903  se->conn.capable |= FUSE_CAP_POSIX_ACL;
1904  if (arg->flags & FUSE_HANDLE_KILLPRIV)
1905  se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV;
1906  } else {
1907  se->conn.max_readahead = 0;
1908  }
1909 
1910  if (se->conn.proto_minor >= 14) {
1911 #ifdef HAVE_SPLICE
1912 #ifdef HAVE_VMSPLICE
1913  se->conn.capable |= FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE;
1914 #endif
1915  se->conn.capable |= FUSE_CAP_SPLICE_READ;
1916 #endif
1917  }
1918  if (se->conn.proto_minor >= 18)
1919  se->conn.capable |= FUSE_CAP_IOCTL_DIR;
1920 
1921  /* Default settings for modern filesystems.
1922  *
1923  * Most of these capabilities were disabled by default in
1924  * libfuse2 for backwards compatibility reasons. In libfuse3,
1925  * we can finally enable them by default (as long as they're
1926  * supported by the kernel).
1927  */
1928 #define LL_SET_DEFAULT(cond, cap) \
1929  if ((cond) && (se->conn.capable & (cap))) \
1930  se->conn.want |= (cap)
1931  LL_SET_DEFAULT(1, FUSE_CAP_ASYNC_READ);
1932  LL_SET_DEFAULT(1, FUSE_CAP_PARALLEL_DIROPS);
1933  LL_SET_DEFAULT(1, FUSE_CAP_AUTO_INVAL_DATA);
1934  LL_SET_DEFAULT(1, FUSE_CAP_HANDLE_KILLPRIV);
1935  LL_SET_DEFAULT(1, FUSE_CAP_ASYNC_DIO);
1936  LL_SET_DEFAULT(1, FUSE_CAP_IOCTL_DIR);
1937  LL_SET_DEFAULT(1, FUSE_CAP_ATOMIC_O_TRUNC);
1938  LL_SET_DEFAULT(se->op.write_buf, FUSE_CAP_SPLICE_READ);
1939  LL_SET_DEFAULT(se->op.getlk && se->op.setlk,
1941  LL_SET_DEFAULT(se->op.flock, FUSE_CAP_FLOCK_LOCKS);
1942  LL_SET_DEFAULT(se->op.readdirplus, FUSE_CAP_READDIRPLUS);
1943  LL_SET_DEFAULT(se->op.readdirplus && se->op.readdir,
1945  se->conn.time_gran = 1;
1946 
1947  if (bufsize < FUSE_MIN_READ_BUFFER) {
1948  fprintf(stderr, "fuse: warning: buffer size too small: %zu\n",
1949  bufsize);
1950  bufsize = FUSE_MIN_READ_BUFFER;
1951  }
1952 
1953  bufsize -= 4096;
1954  if (bufsize < se->conn.max_write)
1955  se->conn.max_write = bufsize;
1956 
1957  se->got_init = 1;
1958  if (se->op.init)
1959  se->op.init(se->userdata, &se->conn);
1960 
1961  if (se->conn.want & (~se->conn.capable)) {
1962  fprintf(stderr, "fuse: error: filesystem requested capabilities "
1963  "0x%x that are not supported by kernel, aborting.\n",
1964  se->conn.want & (~se->conn.capable));
1965  fuse_reply_err(req, EPROTO);
1966  se->error = -EPROTO;
1967  fuse_session_exit(se);
1968  return;
1969  }
1970 
1971  unsigned max_read_mo = get_max_read(se->mo);
1972  if (se->conn.max_read != max_read_mo) {
1973  fprintf(stderr, "fuse: error: init() and fuse_session_new() "
1974  "requested different maximum read size (%u vs %u)\n",
1975  se->conn.max_read, max_read_mo);
1976  fuse_reply_err(req, EPROTO);
1977  se->error = -EPROTO;
1978  fuse_session_exit(se);
1979  return;
1980  }
1981 
1982  /* Always enable big writes, this is superseded
1983  by the max_write option */
1984  outarg.flags |= FUSE_BIG_WRITES;
1985 
1986  if (se->conn.want & FUSE_CAP_ASYNC_READ)
1987  outarg.flags |= FUSE_ASYNC_READ;
1988  if (se->conn.want & FUSE_CAP_POSIX_LOCKS)
1989  outarg.flags |= FUSE_POSIX_LOCKS;
1990  if (se->conn.want & FUSE_CAP_ATOMIC_O_TRUNC)
1991  outarg.flags |= FUSE_ATOMIC_O_TRUNC;
1992  if (se->conn.want & FUSE_CAP_EXPORT_SUPPORT)
1993  outarg.flags |= FUSE_EXPORT_SUPPORT;
1994  if (se->conn.want & FUSE_CAP_DONT_MASK)
1995  outarg.flags |= FUSE_DONT_MASK;
1996  if (se->conn.want & FUSE_CAP_FLOCK_LOCKS)
1997  outarg.flags |= FUSE_FLOCK_LOCKS;
1998  if (se->conn.want & FUSE_CAP_AUTO_INVAL_DATA)
1999  outarg.flags |= FUSE_AUTO_INVAL_DATA;
2000  if (se->conn.want & FUSE_CAP_READDIRPLUS)
2001  outarg.flags |= FUSE_DO_READDIRPLUS;
2002  if (se->conn.want & FUSE_CAP_READDIRPLUS_AUTO)
2003  outarg.flags |= FUSE_READDIRPLUS_AUTO;
2004  if (se->conn.want & FUSE_CAP_ASYNC_DIO)
2005  outarg.flags |= FUSE_ASYNC_DIO;
2006  if (se->conn.want & FUSE_CAP_WRITEBACK_CACHE)
2007  outarg.flags |= FUSE_WRITEBACK_CACHE;
2008  if (se->conn.want & FUSE_CAP_POSIX_ACL)
2009  outarg.flags |= FUSE_POSIX_ACL;
2010  outarg.max_readahead = se->conn.max_readahead;
2011  outarg.max_write = se->conn.max_write;
2012  if (se->conn.proto_minor >= 13) {
2013  if (se->conn.max_background >= (1 << 16))
2014  se->conn.max_background = (1 << 16) - 1;
2015  if (se->conn.congestion_threshold > se->conn.max_background)
2016  se->conn.congestion_threshold = se->conn.max_background;
2017  if (!se->conn.congestion_threshold) {
2018  se->conn.congestion_threshold =
2019  se->conn.max_background * 3 / 4;
2020  }
2021 
2022  outarg.max_background = se->conn.max_background;
2023  outarg.congestion_threshold = se->conn.congestion_threshold;
2024  }
2025  if (se->conn.proto_minor >= 23)
2026  outarg.time_gran = se->conn.time_gran;
2027 
2028  if (se->debug) {
2029  fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor);
2030  fprintf(stderr, " flags=0x%08x\n", outarg.flags);
2031  fprintf(stderr, " max_readahead=0x%08x\n",
2032  outarg.max_readahead);
2033  fprintf(stderr, " max_write=0x%08x\n", outarg.max_write);
2034  fprintf(stderr, " max_background=%i\n",
2035  outarg.max_background);
2036  fprintf(stderr, " congestion_threshold=%i\n",
2037  outarg.congestion_threshold);
2038  fprintf(stderr, " time_gran=%u\n",
2039  outarg.time_gran);
2040  }
2041  if (arg->minor < 5)
2042  outargsize = FUSE_COMPAT_INIT_OUT_SIZE;
2043  else if (arg->minor < 23)
2044  outargsize = FUSE_COMPAT_22_INIT_OUT_SIZE;
2045 
2046  send_reply_ok(req, &outarg, outargsize);
2047 }
2048 
2049 static void do_destroy(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
2050 {
2051  struct fuse_session *se = req->se;
2052 
2053  (void) nodeid;
2054  (void) inarg;
2055 
2056  se->got_destroy = 1;
2057  if (se->op.destroy)
2058  se->op.destroy(se->userdata);
2059 
2060  send_reply_ok(req, NULL, 0);
2061 }
2062 
2063 static void list_del_nreq(struct fuse_notify_req *nreq)
2064 {
2065  struct fuse_notify_req *prev = nreq->prev;
2066  struct fuse_notify_req *next = nreq->next;
2067  prev->next = next;
2068  next->prev = prev;
2069 }
2070 
2071 static void list_add_nreq(struct fuse_notify_req *nreq,
2072  struct fuse_notify_req *next)
2073 {
2074  struct fuse_notify_req *prev = next->prev;
2075  nreq->next = next;
2076  nreq->prev = prev;
2077  prev->next = nreq;
2078  next->prev = nreq;
2079 }
2080 
2081 static void list_init_nreq(struct fuse_notify_req *nreq)
2082 {
2083  nreq->next = nreq;
2084  nreq->prev = nreq;
2085 }
2086 
2087 static void do_notify_reply(fuse_req_t req, fuse_ino_t nodeid,
2088  const void *inarg, const struct fuse_buf *buf)
2089 {
2090  struct fuse_session *se = req->se;
2091  struct fuse_notify_req *nreq;
2092  struct fuse_notify_req *head;
2093 
2094  pthread_mutex_lock(&se->lock);
2095  head = &se->notify_list;
2096  for (nreq = head->next; nreq != head; nreq = nreq->next) {
2097  if (nreq->unique == req->unique) {
2098  list_del_nreq(nreq);
2099  break;
2100  }
2101  }
2102  pthread_mutex_unlock(&se->lock);
2103 
2104  if (nreq != head)
2105  nreq->reply(nreq, req, nodeid, inarg, buf);
2106 }
2107 
2108 static int send_notify_iov(struct fuse_session *se, int notify_code,
2109  struct iovec *iov, int count)
2110 {
2111  struct fuse_out_header out;
2112 
2113  if (!se->got_init)
2114  return -ENOTCONN;
2115 
2116  out.unique = 0;
2117  out.error = notify_code;
2118  iov[0].iov_base = &out;
2119  iov[0].iov_len = sizeof(struct fuse_out_header);
2120 
2121  return fuse_send_msg(se, NULL, iov, count);
2122 }
2123 
2124 int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
2125 {
2126  if (ph != NULL) {
2127  struct fuse_notify_poll_wakeup_out outarg;
2128  struct iovec iov[2];
2129 
2130  outarg.kh = ph->kh;
2131 
2132  iov[1].iov_base = &outarg;
2133  iov[1].iov_len = sizeof(outarg);
2134 
2135  return send_notify_iov(ph->se, FUSE_NOTIFY_POLL, iov, 2);
2136  } else {
2137  return 0;
2138  }
2139 }
2140 
2141 int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino,
2142  off_t off, off_t len)
2143 {
2144  struct fuse_notify_inval_inode_out outarg;
2145  struct iovec iov[2];
2146 
2147  if (!se)
2148  return -EINVAL;
2149 
2150  if (se->conn.proto_major < 6 || se->conn.proto_minor < 12)
2151  return -ENOSYS;
2152 
2153  outarg.ino = ino;
2154  outarg.off = off;
2155  outarg.len = len;
2156 
2157  iov[1].iov_base = &outarg;
2158  iov[1].iov_len = sizeof(outarg);
2159 
2160  return send_notify_iov(se, FUSE_NOTIFY_INVAL_INODE, iov, 2);
2161 }
2162 
2163 int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent,
2164  const char *name, size_t namelen)
2165 {
2166  struct fuse_notify_inval_entry_out outarg;
2167  struct iovec iov[3];
2168 
2169  if (!se)
2170  return -EINVAL;
2171 
2172  if (se->conn.proto_major < 6 || se->conn.proto_minor < 12)
2173  return -ENOSYS;
2174 
2175  outarg.parent = parent;
2176  outarg.namelen = namelen;
2177  outarg.padding = 0;
2178 
2179  iov[1].iov_base = &outarg;
2180  iov[1].iov_len = sizeof(outarg);
2181  iov[2].iov_base = (void *)name;
2182  iov[2].iov_len = namelen + 1;
2183 
2184  return send_notify_iov(se, FUSE_NOTIFY_INVAL_ENTRY, iov, 3);
2185 }
2186 
2187 int fuse_lowlevel_notify_delete(struct fuse_session *se,
2188  fuse_ino_t parent, fuse_ino_t child,
2189  const char *name, size_t namelen)
2190 {
2191  struct fuse_notify_delete_out outarg;
2192  struct iovec iov[3];
2193 
2194  if (!se)
2195  return -EINVAL;
2196 
2197  if (se->conn.proto_major < 6 || se->conn.proto_minor < 18)
2198  return -ENOSYS;
2199 
2200  outarg.parent = parent;
2201  outarg.child = child;
2202  outarg.namelen = namelen;
2203  outarg.padding = 0;
2204 
2205  iov[1].iov_base = &outarg;
2206  iov[1].iov_len = sizeof(outarg);
2207  iov[2].iov_base = (void *)name;
2208  iov[2].iov_len = namelen + 1;
2209 
2210  return send_notify_iov(se, FUSE_NOTIFY_DELETE, iov, 3);
2211 }
2212 
2213 int fuse_lowlevel_notify_store(struct fuse_session *se, fuse_ino_t ino,
2214  off_t offset, struct fuse_bufvec *bufv,
2215  enum fuse_buf_copy_flags flags)
2216 {
2217  struct fuse_out_header out;
2218  struct fuse_notify_store_out outarg;
2219  struct iovec iov[3];
2220  size_t size = fuse_buf_size(bufv);
2221  int res;
2222 
2223  if (!se)
2224  return -EINVAL;
2225 
2226  if (se->conn.proto_major < 6 || se->conn.proto_minor < 15)
2227  return -ENOSYS;
2228 
2229  out.unique = 0;
2230  out.error = FUSE_NOTIFY_STORE;
2231 
2232  outarg.nodeid = ino;
2233  outarg.offset = offset;
2234  outarg.size = size;
2235  outarg.padding = 0;
2236 
2237  iov[0].iov_base = &out;
2238  iov[0].iov_len = sizeof(out);
2239  iov[1].iov_base = &outarg;
2240  iov[1].iov_len = sizeof(outarg);
2241 
2242  res = fuse_send_data_iov(se, NULL, iov, 2, bufv, flags);
2243  if (res > 0)
2244  res = -res;
2245 
2246  return res;
2247 }
2248 
2249 struct fuse_retrieve_req {
2250  struct fuse_notify_req nreq;
2251  void *cookie;
2252 };
2253 
2254 static void fuse_ll_retrieve_reply(struct fuse_notify_req *nreq,
2255  fuse_req_t req, fuse_ino_t ino,
2256  const void *inarg,
2257  const struct fuse_buf *ibuf)
2258 {
2259  struct fuse_session *se = req->se;
2260  struct fuse_retrieve_req *rreq =
2261  container_of(nreq, struct fuse_retrieve_req, nreq);
2262  const struct fuse_notify_retrieve_in *arg = inarg;
2263  struct fuse_bufvec bufv = {
2264  .buf[0] = *ibuf,
2265  .count = 1,
2266  };
2267 
2268  if (!(bufv.buf[0].flags & FUSE_BUF_IS_FD))
2269  bufv.buf[0].mem = PARAM(arg);
2270 
2271  bufv.buf[0].size -= sizeof(struct fuse_in_header) +
2272  sizeof(struct fuse_notify_retrieve_in);
2273 
2274  if (bufv.buf[0].size < arg->size) {
2275  fprintf(stderr, "fuse: retrieve reply: buffer size too small\n");
2276  fuse_reply_none(req);
2277  goto out;
2278  }
2279  bufv.buf[0].size = arg->size;
2280 
2281  if (se->op.retrieve_reply) {
2282  se->op.retrieve_reply(req, rreq->cookie, ino,
2283  arg->offset, &bufv);
2284  } else {
2285  fuse_reply_none(req);
2286  }
2287 out:
2288  free(rreq);
2289  if ((ibuf->flags & FUSE_BUF_IS_FD) && bufv.idx < bufv.count)
2290  fuse_ll_clear_pipe(se);
2291 }
2292 
2293 int fuse_lowlevel_notify_retrieve(struct fuse_session *se, fuse_ino_t ino,
2294  size_t size, off_t offset, void *cookie)
2295 {
2296  struct fuse_notify_retrieve_out outarg;
2297  struct iovec iov[2];
2298  struct fuse_retrieve_req *rreq;
2299  int err;
2300 
2301  if (!se)
2302  return -EINVAL;
2303 
2304  if (se->conn.proto_major < 6 || se->conn.proto_minor < 15)
2305  return -ENOSYS;
2306 
2307  rreq = malloc(sizeof(*rreq));
2308  if (rreq == NULL)
2309  return -ENOMEM;
2310 
2311  pthread_mutex_lock(&se->lock);
2312  rreq->cookie = cookie;
2313  rreq->nreq.unique = se->notify_ctr++;
2314  rreq->nreq.reply = fuse_ll_retrieve_reply;
2315  list_add_nreq(&rreq->nreq, &se->notify_list);
2316  pthread_mutex_unlock(&se->lock);
2317 
2318  outarg.notify_unique = rreq->nreq.unique;
2319  outarg.nodeid = ino;
2320  outarg.offset = offset;
2321  outarg.size = size;
2322  outarg.padding = 0;
2323 
2324  iov[1].iov_base = &outarg;
2325  iov[1].iov_len = sizeof(outarg);
2326 
2327  err = send_notify_iov(se, FUSE_NOTIFY_RETRIEVE, iov, 2);
2328  if (err) {
2329  pthread_mutex_lock(&se->lock);
2330  list_del_nreq(&rreq->nreq);
2331  pthread_mutex_unlock(&se->lock);
2332  free(rreq);
2333  }
2334 
2335  return err;
2336 }
2337 
2339 {
2340  return req->se->userdata;
2341 }
2342 
2344 {
2345  return &req->ctx;
2346 }
2347 
2349  void *data)
2350 {
2351  pthread_mutex_lock(&req->lock);
2352  pthread_mutex_lock(&req->se->lock);
2353  req->u.ni.func = func;
2354  req->u.ni.data = data;
2355  pthread_mutex_unlock(&req->se->lock);
2356  if (req->interrupted && func)
2357  func(req, data);
2358  pthread_mutex_unlock(&req->lock);
2359 }
2360 
2362 {
2363  int interrupted;
2364 
2365  pthread_mutex_lock(&req->se->lock);
2366  interrupted = req->interrupted;
2367  pthread_mutex_unlock(&req->se->lock);
2368 
2369  return interrupted;
2370 }
2371 
2372 static struct {
2373  void (*func)(fuse_req_t, fuse_ino_t, const void *);
2374  const char *name;
2375 } fuse_ll_ops[] = {
2376  [FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
2377  [FUSE_FORGET] = { do_forget, "FORGET" },
2378  [FUSE_GETATTR] = { do_getattr, "GETATTR" },
2379  [FUSE_SETATTR] = { do_setattr, "SETATTR" },
2380  [FUSE_READLINK] = { do_readlink, "READLINK" },
2381  [FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
2382  [FUSE_MKNOD] = { do_mknod, "MKNOD" },
2383  [FUSE_MKDIR] = { do_mkdir, "MKDIR" },
2384  [FUSE_UNLINK] = { do_unlink, "UNLINK" },
2385  [FUSE_RMDIR] = { do_rmdir, "RMDIR" },
2386  [FUSE_RENAME] = { do_rename, "RENAME" },
2387  [FUSE_LINK] = { do_link, "LINK" },
2388  [FUSE_OPEN] = { do_open, "OPEN" },
2389  [FUSE_READ] = { do_read, "READ" },
2390  [FUSE_WRITE] = { do_write, "WRITE" },
2391  [FUSE_STATFS] = { do_statfs, "STATFS" },
2392  [FUSE_RELEASE] = { do_release, "RELEASE" },
2393  [FUSE_FSYNC] = { do_fsync, "FSYNC" },
2394  [FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
2395  [FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
2396  [FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
2397  [FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
2398  [FUSE_FLUSH] = { do_flush, "FLUSH" },
2399  [FUSE_INIT] = { do_init, "INIT" },
2400  [FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
2401  [FUSE_READDIR] = { do_readdir, "READDIR" },
2402  [FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
2403  [FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
2404  [FUSE_GETLK] = { do_getlk, "GETLK" },
2405  [FUSE_SETLK] = { do_setlk, "SETLK" },
2406  [FUSE_SETLKW] = { do_setlkw, "SETLKW" },
2407  [FUSE_ACCESS] = { do_access, "ACCESS" },
2408  [FUSE_CREATE] = { do_create, "CREATE" },
2409  [FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
2410  [FUSE_BMAP] = { do_bmap, "BMAP" },
2411  [FUSE_IOCTL] = { do_ioctl, "IOCTL" },
2412  [FUSE_POLL] = { do_poll, "POLL" },
2413  [FUSE_FALLOCATE] = { do_fallocate, "FALLOCATE" },
2414  [FUSE_DESTROY] = { do_destroy, "DESTROY" },
2415  [FUSE_NOTIFY_REPLY] = { (void *) 1, "NOTIFY_REPLY" },
2416  [FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
2417  [FUSE_READDIRPLUS] = { do_readdirplus, "READDIRPLUS"},
2418  [FUSE_RENAME2] = { do_rename2, "RENAME2" },
2419  [FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" },
2420  [CUSE_INIT] = { cuse_lowlevel_init, "CUSE_INIT" },
2421 };
2422 
2423 #define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
2424 
2425 static const char *opname(enum fuse_opcode opcode)
2426 {
2427  if (opcode >= FUSE_MAXOP || !fuse_ll_ops[opcode].name)
2428  return "???";
2429  else
2430  return fuse_ll_ops[opcode].name;
2431 }
2432 
2433 static int fuse_ll_copy_from_pipe(struct fuse_bufvec *dst,
2434  struct fuse_bufvec *src)
2435 {
2436  ssize_t res = fuse_buf_copy(dst, src, 0);
2437  if (res < 0) {
2438  fprintf(stderr, "fuse: copy from pipe: %s\n", strerror(-res));
2439  return res;
2440  }
2441  if ((size_t)res < fuse_buf_size(dst)) {
2442  fprintf(stderr, "fuse: copy from pipe: short read\n");
2443  return -1;
2444  }
2445  return 0;
2446 }
2447 
2448 void fuse_session_process_buf(struct fuse_session *se,
2449  const struct fuse_buf *buf)
2450 {
2451  fuse_session_process_buf_int(se, buf, NULL);
2452 }
2453 
2454 void fuse_session_process_buf_int(struct fuse_session *se,
2455  const struct fuse_buf *buf, struct fuse_chan *ch)
2456 {
2457  const size_t write_header_size = sizeof(struct fuse_in_header) +
2458  sizeof(struct fuse_write_in);
2459  struct fuse_bufvec bufv = { .buf[0] = *buf, .count = 1 };
2460  struct fuse_bufvec tmpbuf = FUSE_BUFVEC_INIT(write_header_size);
2461  struct fuse_in_header *in;
2462  const void *inarg;
2463  struct fuse_req *req;
2464  void *mbuf = NULL;
2465  int err;
2466  int res;
2467 
2468  if (buf->flags & FUSE_BUF_IS_FD) {
2469  if (buf->size < tmpbuf.buf[0].size)
2470  tmpbuf.buf[0].size = buf->size;
2471 
2472  mbuf = malloc(tmpbuf.buf[0].size);
2473  if (mbuf == NULL) {
2474  fprintf(stderr, "fuse: failed to allocate header\n");
2475  goto clear_pipe;
2476  }
2477  tmpbuf.buf[0].mem = mbuf;
2478 
2479  res = fuse_ll_copy_from_pipe(&tmpbuf, &bufv);
2480  if (res < 0)
2481  goto clear_pipe;
2482 
2483  in = mbuf;
2484  } else {
2485  in = buf->mem;
2486  }
2487 
2488  if (se->debug) {
2489  fprintf(stderr,
2490  "unique: %llu, opcode: %s (%i), nodeid: %llu, insize: %zu, pid: %u\n",
2491  (unsigned long long) in->unique,
2492  opname((enum fuse_opcode) in->opcode), in->opcode,
2493  (unsigned long long) in->nodeid, buf->size, in->pid);
2494  }
2495 
2496  req = fuse_ll_alloc_req(se);
2497  if (req == NULL) {
2498  struct fuse_out_header out = {
2499  .unique = in->unique,
2500  .error = -ENOMEM,
2501  };
2502  struct iovec iov = {
2503  .iov_base = &out,
2504  .iov_len = sizeof(struct fuse_out_header),
2505  };
2506 
2507  fuse_send_msg(se, ch, &iov, 1);
2508  goto clear_pipe;
2509  }
2510 
2511  req->unique = in->unique;
2512  req->ctx.uid = in->uid;
2513  req->ctx.gid = in->gid;
2514  req->ctx.pid = in->pid;
2515  req->ch = ch ? fuse_chan_get(ch) : NULL;
2516 
2517  err = EIO;
2518  if (!se->got_init) {
2519  enum fuse_opcode expected;
2520 
2521  expected = se->cuse_data ? CUSE_INIT : FUSE_INIT;
2522  if (in->opcode != expected)
2523  goto reply_err;
2524  } else if (in->opcode == FUSE_INIT || in->opcode == CUSE_INIT)
2525  goto reply_err;
2526 
2527  err = EACCES;
2528  /* Implement -o allow_root */
2529  if (se->deny_others && in->uid != se->owner && in->uid != 0 &&
2530  in->opcode != FUSE_INIT && in->opcode != FUSE_READ &&
2531  in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC &&
2532  in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&
2533  in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR &&
2534  in->opcode != FUSE_NOTIFY_REPLY &&
2535  in->opcode != FUSE_READDIRPLUS)
2536  goto reply_err;
2537 
2538  err = ENOSYS;
2539  if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func)
2540  goto reply_err;
2541  if (in->opcode != FUSE_INTERRUPT) {
2542  struct fuse_req *intr;
2543  pthread_mutex_lock(&se->lock);
2544  intr = check_interrupt(se, req);
2545  list_add_req(req, &se->list);
2546  pthread_mutex_unlock(&se->lock);
2547  if (intr)
2548  fuse_reply_err(intr, EAGAIN);
2549  }
2550 
2551  if ((buf->flags & FUSE_BUF_IS_FD) && write_header_size < buf->size &&
2552  (in->opcode != FUSE_WRITE || !se->op.write_buf) &&
2553  in->opcode != FUSE_NOTIFY_REPLY) {
2554  void *newmbuf;
2555 
2556  err = ENOMEM;
2557  newmbuf = realloc(mbuf, buf->size);
2558  if (newmbuf == NULL)
2559  goto reply_err;
2560  mbuf = newmbuf;
2561 
2562  tmpbuf = FUSE_BUFVEC_INIT(buf->size - write_header_size);
2563  tmpbuf.buf[0].mem = mbuf + write_header_size;
2564 
2565  res = fuse_ll_copy_from_pipe(&tmpbuf, &bufv);
2566  err = -res;
2567  if (res < 0)
2568  goto reply_err;
2569 
2570  in = mbuf;
2571  }
2572 
2573  inarg = (void *) &in[1];
2574  if (in->opcode == FUSE_WRITE && se->op.write_buf)
2575  do_write_buf(req, in->nodeid, inarg, buf);
2576  else if (in->opcode == FUSE_NOTIFY_REPLY)
2577  do_notify_reply(req, in->nodeid, inarg, buf);
2578  else
2579  fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg);
2580 
2581 out_free:
2582  free(mbuf);
2583  return;
2584 
2585 reply_err:
2586  fuse_reply_err(req, err);
2587 clear_pipe:
2588  if (buf->flags & FUSE_BUF_IS_FD)
2589  fuse_ll_clear_pipe(se);
2590  goto out_free;
2591 }
2592 
2593 #define LL_OPTION(n,o,v) \
2594  { n, offsetof(struct fuse_session, o), v }
2595 
2596 static const struct fuse_opt fuse_ll_opts[] = {
2597  LL_OPTION("debug", debug, 1),
2598  LL_OPTION("-d", debug, 1),
2599  LL_OPTION("--debug", debug, 1),
2600  LL_OPTION("allow_root", deny_others, 1),
2601  FUSE_OPT_END
2602 };
2603 
2605 {
2606  printf("using FUSE kernel interface version %i.%i\n",
2607  FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
2608  fuse_mount_version();
2609 }
2610 
2612 {
2613  /* These are not all options, but the ones that are
2614  potentially of interest to an end-user */
2615  printf(
2616 " -o allow_other allow access by all users\n"
2617 " -o allow_root allow access by root\n"
2618 " -o auto_unmount auto unmount on process termination\n");
2619 }
2620 
2621 void fuse_session_destroy(struct fuse_session *se)
2622 {
2623  struct fuse_ll_pipe *llp;
2624 
2625  if (se->got_init && !se->got_destroy) {
2626  if (se->op.destroy)
2627  se->op.destroy(se->userdata);
2628  }
2629  llp = pthread_getspecific(se->pipe_key);
2630  if (llp != NULL)
2631  fuse_ll_pipe_free(llp);
2632  pthread_key_delete(se->pipe_key);
2633  pthread_mutex_destroy(&se->lock);
2634  free(se->cuse_data);
2635  if (se->fd != -1)
2636  close(se->fd);
2637  destroy_mount_opts(se->mo);
2638  free(se);
2639 }
2640 
2641 
2642 static void fuse_ll_pipe_destructor(void *data)
2643 {
2644  struct fuse_ll_pipe *llp = data;
2645  fuse_ll_pipe_free(llp);
2646 }
2647 
2648 int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf)
2649 {
2650  return fuse_session_receive_buf_int(se, buf, NULL);
2651 }
2652 
2653 int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf,
2654  struct fuse_chan *ch)
2655 {
2656  int err;
2657  ssize_t res;
2658 #ifdef HAVE_SPLICE
2659  size_t bufsize = se->bufsize;
2660  struct fuse_ll_pipe *llp;
2661  struct fuse_buf tmpbuf;
2662 
2663  if (se->conn.proto_minor < 14 || !(se->conn.want & FUSE_CAP_SPLICE_READ))
2664  goto fallback;
2665 
2666  llp = fuse_ll_get_pipe(se);
2667  if (llp == NULL)
2668  goto fallback;
2669 
2670  if (llp->size < bufsize) {
2671  if (llp->can_grow) {
2672  res = fcntl(llp->pipe[0], F_SETPIPE_SZ, bufsize);
2673  if (res == -1) {
2674  llp->can_grow = 0;
2675  goto fallback;
2676  }
2677  llp->size = res;
2678  }
2679  if (llp->size < bufsize)
2680  goto fallback;
2681  }
2682 
2683  res = splice(ch ? ch->fd : se->fd,
2684  NULL, llp->pipe[1], NULL, bufsize, 0);
2685  err = errno;
2686 
2687  if (fuse_session_exited(se))
2688  return 0;
2689 
2690  if (res == -1) {
2691  if (err == ENODEV) {
2692  /* Filesystem was unmounted, or connection was aborted
2693  via /sys/fs/fuse/connections */
2694  fuse_session_exit(se);
2695  return 0;
2696  }
2697  if (err != EINTR && err != EAGAIN)
2698  perror("fuse: splice from device");
2699  return -err;
2700  }
2701 
2702  if (res < sizeof(struct fuse_in_header)) {
2703  fprintf(stderr, "short splice from fuse device\n");
2704  return -EIO;
2705  }
2706 
2707  tmpbuf = (struct fuse_buf) {
2708  .size = res,
2709  .flags = FUSE_BUF_IS_FD,
2710  .fd = llp->pipe[0],
2711  };
2712 
2713  /*
2714  * Don't bother with zero copy for small requests.
2715  * fuse_loop_mt() needs to check for FORGET so this more than
2716  * just an optimization.
2717  */
2718  if (res < sizeof(struct fuse_in_header) +
2719  sizeof(struct fuse_write_in) + pagesize) {
2720  struct fuse_bufvec src = { .buf[0] = tmpbuf, .count = 1 };
2721  struct fuse_bufvec dst = { .count = 1 };
2722 
2723  if (!buf->mem) {
2724  buf->mem = malloc(se->bufsize);
2725  if (!buf->mem) {
2726  fprintf(stderr,
2727  "fuse: failed to allocate read buffer\n");
2728  return -ENOMEM;
2729  }
2730  }
2731  buf->size = se->bufsize;
2732  buf->flags = 0;
2733  dst.buf[0] = *buf;
2734 
2735  res = fuse_buf_copy(&dst, &src, 0);
2736  if (res < 0) {
2737  fprintf(stderr, "fuse: copy from pipe: %s\n",
2738  strerror(-res));
2739  fuse_ll_clear_pipe(se);
2740  return res;
2741  }
2742  if (res < tmpbuf.size) {
2743  fprintf(stderr, "fuse: copy from pipe: short read\n");
2744  fuse_ll_clear_pipe(se);
2745  return -EIO;
2746  }
2747  assert(res == tmpbuf.size);
2748 
2749  } else {
2750  /* Don't overwrite buf->mem, as that would cause a leak */
2751  buf->fd = tmpbuf.fd;
2752  buf->flags = tmpbuf.flags;
2753  }
2754  buf->size = tmpbuf.size;
2755 
2756  return res;
2757 
2758 fallback:
2759 #endif
2760  if (!buf->mem) {
2761  buf->mem = malloc(se->bufsize);
2762  if (!buf->mem) {
2763  fprintf(stderr,
2764  "fuse: failed to allocate read buffer\n");
2765  return -ENOMEM;
2766  }
2767  }
2768 
2769 restart:
2770  res = read(ch ? ch->fd : se->fd, buf->mem, se->bufsize);
2771  err = errno;
2772 
2773  if (fuse_session_exited(se))
2774  return 0;
2775  if (res == -1) {
2776  /* ENOENT means the operation was interrupted, it's safe
2777  to restart */
2778  if (err == ENOENT)
2779  goto restart;
2780 
2781  if (err == ENODEV) {
2782  /* Filesystem was unmounted, or connection was aborted
2783  via /sys/fs/fuse/connections */
2784  fuse_session_exit(se);
2785  return 0;
2786  }
2787  /* Errors occurring during normal operation: EINTR (read
2788  interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
2789  umounted) */
2790  if (err != EINTR && err != EAGAIN)
2791  perror("fuse: reading device");
2792  return -err;
2793  }
2794  if ((size_t) res < sizeof(struct fuse_in_header)) {
2795  fprintf(stderr, "short read on fuse device\n");
2796  return -EIO;
2797  }
2798 
2799  buf->size = res;
2800 
2801  return res;
2802 }
2803 
2804 #define KERNEL_BUF_PAGES 32
2805 
2806 /* room needed in buffer to accommodate header */
2807 #define HEADER_SIZE 0x1000
2808 
2809 struct fuse_session *fuse_session_new(struct fuse_args *args,
2810  const struct fuse_lowlevel_ops *op,
2811  size_t op_size, void *userdata)
2812 {
2813  int err;
2814  struct fuse_session *se;
2815  struct mount_opts *mo;
2816 
2817  if (sizeof(struct fuse_lowlevel_ops) < op_size) {
2818  fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");
2819  op_size = sizeof(struct fuse_lowlevel_ops);
2820  }
2821 
2822  if (args->argc == 0) {
2823  fprintf(stderr, "fuse: empty argv passed to fuse_session_new().\n");
2824  return NULL;
2825  }
2826 
2827  se = (struct fuse_session *) calloc(1, sizeof(struct fuse_session));
2828  if (se == NULL) {
2829  fprintf(stderr, "fuse: failed to allocate fuse object\n");
2830  goto out1;
2831  }
2832  se->fd = -1;
2833  se->conn.max_write = UINT_MAX;
2834  se->conn.max_readahead = UINT_MAX;
2835 
2836  /* Parse options */
2837  if(fuse_opt_parse(args, se, fuse_ll_opts, NULL) == -1)
2838  goto out2;
2839  if(se->deny_others) {
2840  /* Allowing access only by root is done by instructing
2841  * kernel to allow access by everyone, and then restricting
2842  * access to root and mountpoint owner in libfuse.
2843  */
2844  // We may be adding the option a second time, but
2845  // that doesn't hurt.
2846  if(fuse_opt_add_arg(args, "-oallow_other") == -1)
2847  goto out2;
2848  }
2849  mo = parse_mount_opts(args);
2850  if (mo == NULL)
2851  goto out3;
2852 
2853  if(args->argc == 1 &&
2854  args->argv[0][0] == '-') {
2855  fprintf(stderr, "fuse: warning: argv[0] looks like an option, but "
2856  "will be ignored\n");
2857  } else if (args->argc != 1) {
2858  int i;
2859  fprintf(stderr, "fuse: unknown option(s): `");
2860  for(i = 1; i < args->argc-1; i++)
2861  fprintf(stderr, "%s ", args->argv[i]);
2862  fprintf(stderr, "%s'\n", args->argv[i]);
2863  goto out4;
2864  }
2865 
2866  if (se->debug)
2867  fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
2868 
2869  se->bufsize = KERNEL_BUF_PAGES * getpagesize() + HEADER_SIZE;
2870 
2871  list_init_req(&se->list);
2872  list_init_req(&se->interrupts);
2873  list_init_nreq(&se->notify_list);
2874  se->notify_ctr = 1;
2875  fuse_mutex_init(&se->lock);
2876 
2877  err = pthread_key_create(&se->pipe_key, fuse_ll_pipe_destructor);
2878  if (err) {
2879  fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
2880  strerror(err));
2881  goto out5;
2882  }
2883 
2884  memcpy(&se->op, op, op_size);
2885  se->owner = getuid();
2886  se->userdata = userdata;
2887 
2888  se->mo = mo;
2889  return se;
2890 
2891 out5:
2892  pthread_mutex_destroy(&se->lock);
2893 out4:
2894  fuse_opt_free_args(args);
2895 out3:
2896  free(mo);
2897 out2:
2898  free(se);
2899 out1:
2900  return NULL;
2901 }
2902 
2903 int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
2904 {
2905  int fd;
2906 
2907  /*
2908  * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
2909  * would ensue.
2910  */
2911  do {
2912  fd = open("/dev/null", O_RDWR);
2913  if (fd > 2)
2914  close(fd);
2915  } while (fd >= 0 && fd <= 2);
2916 
2917  /*
2918  * To allow FUSE daemons to run without privileges, the caller may open
2919  * /dev/fuse before launching the file system and pass on the file
2920  * descriptor by specifying /dev/fd/N as the mount point. Note that the
2921  * parent process takes care of performing the mount in this case.
2922  */
2923  fd = fuse_mnt_parse_fuse_fd(mountpoint);
2924  if (fd != -1) {
2925  if (fcntl(fd, F_GETFD) == -1) {
2926  fprintf(stderr,
2927  "fuse: Invalid file descriptor /dev/fd/%u\n",
2928  fd);
2929  return -1;
2930  }
2931  se->fd = fd;
2932  return 0;
2933  }
2934 
2935  /* Open channel */
2936  fd = fuse_kern_mount(mountpoint, se->mo);
2937  if (fd == -1)
2938  return -1;
2939  se->fd = fd;
2940 
2941  /* Save mountpoint */
2942  se->mountpoint = strdup(mountpoint);
2943  if (se->mountpoint == NULL)
2944  goto error_out;
2945 
2946  return 0;
2947 
2948 error_out:
2949  fuse_kern_unmount(mountpoint, fd);
2950  return -1;
2951 }
2952 
2953 int fuse_session_fd(struct fuse_session *se)
2954 {
2955  return se->fd;
2956 }
2957 
2958 void fuse_session_unmount(struct fuse_session *se)
2959 {
2960  if (se->mountpoint != NULL) {
2961  fuse_kern_unmount(se->mountpoint, se->fd);
2962  free(se->mountpoint);
2963  se->mountpoint = NULL;
2964  }
2965 }
2966 
2967 #ifdef linux
2968 int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
2969 {
2970  char *buf;
2971  size_t bufsize = 1024;
2972  char path[128];
2973  int ret;
2974  int fd;
2975  unsigned long pid = req->ctx.pid;
2976  char *s;
2977 
2978  sprintf(path, "/proc/%lu/task/%lu/status", pid, pid);
2979 
2980 retry:
2981  buf = malloc(bufsize);
2982  if (buf == NULL)
2983  return -ENOMEM;
2984 
2985  ret = -EIO;
2986  fd = open(path, O_RDONLY);
2987  if (fd == -1)
2988  goto out_free;
2989 
2990  ret = read(fd, buf, bufsize);
2991  close(fd);
2992  if (ret < 0) {
2993  ret = -EIO;
2994  goto out_free;
2995  }
2996 
2997  if ((size_t)ret == bufsize) {
2998  free(buf);
2999  bufsize *= 4;
3000  goto retry;
3001  }
3002 
3003  ret = -EIO;
3004  s = strstr(buf, "\nGroups:");
3005  if (s == NULL)
3006  goto out_free;
3007 
3008  s += 8;
3009  ret = 0;
3010  while (1) {
3011  char *end;
3012  unsigned long val = strtoul(s, &end, 0);
3013  if (end == s)
3014  break;
3015 
3016  s = end;
3017  if (ret < size)
3018  list[ret] = val;
3019  ret++;
3020  }
3021 
3022 out_free:
3023  free(buf);
3024  return ret;
3025 }
3026 #else /* linux */
3027 /*
3028  * This is currently not implemented on other than Linux...
3029  */
3030 int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
3031 {
3032  (void) req; (void) size; (void) list;
3033  return -ENOSYS;
3034 }
3035 #endif
3036 
3037 void fuse_session_exit(struct fuse_session *se)
3038 {
3039  se->exited = 1;
3040 }
3041 
3042 void fuse_session_reset(struct fuse_session *se)
3043 {
3044  se->exited = 0;
3045  se->error = 0;
3046 }
3047 
3048 int fuse_session_exited(struct fuse_session *se)
3049 {
3050  return se->exited;
3051 }
void fuse_session_destroy(struct fuse_session *se)
+
int fuse_reply_err(fuse_req_t req, int err)
+
size_t off
Definition: fuse_common.h:679
+
#define FUSE_CAP_IOCTL_DIR
Definition: fuse_common.h:197
+
int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf)
+
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
+
void fuse_session_exit(struct fuse_session *se)
+
uint64_t fh
Definition: fuse_common.h:72
+
int fuse_lowlevel_notify_retrieve(struct fuse_session *se, fuse_ino_t ino, size_t size, off_t offset, void *cookie)
+
int fuse_lowlevel_notify_delete(struct fuse_session *se, fuse_ino_t parent, fuse_ino_t child, const char *name, size_t namelen)
+
unsigned int writepage
Definition: fuse_common.h:43
+
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
+
void fuse_lowlevel_help(void)
+
int argc
Definition: fuse_opt.h:111
+
unsigned int direct_io
Definition: fuse_common.h:46
+ +
#define FUSE_CAP_HANDLE_KILLPRIV
Definition: fuse_common.h:317
+
size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct fuse_entry_param *e, off_t off)
+
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
+
uint32_t poll_events
Definition: fuse_common.h:79
+
int fuse_session_fd(struct fuse_session *se)
+
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
+ +
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
+
#define FUSE_CAP_ASYNC_READ
Definition: fuse_common.h:120
+
int fuse_reply_ioctl_retry(fuse_req_t req, const struct iovec *in_iov, size_t in_count, const struct iovec *out_iov, size_t out_count)
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
void(* fuse_interrupt_func_t)(fuse_req_t req, void *data)
+
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
+
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
+
struct stat attr
Definition: fuse_lowlevel.h:91
+
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
+
void * fuse_req_userdata(fuse_req_t req)
+ +
int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
+
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
+
unsigned int keep_cache
Definition: fuse_common.h:51
+
Definition: fuse_lowlevel.h:59
+
#define FUSE_CAP_EXPORT_SUPPORT
Definition: fuse_common.h:144
+
fuse_ino_t ino
Definition: fuse_lowlevel.h:67
+
uint64_t lock_owner
Definition: fuse_common.h:75
+
int fuse_reply_xattr(fuse_req_t req, size_t count)
+
int fuse_session_exited(struct fuse_session *se)
+
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
+
#define FUSE_CAP_READDIRPLUS_AUTO
Definition: fuse_common.h:246
+
#define FUSE_CAP_SPLICE_WRITE
Definition: fuse_common.h:160
+
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:54
+
int fuse_lowlevel_notify_store(struct fuse_session *se, fuse_ino_t ino, off_t offset, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
+ +
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
+
#define FUSE_CAP_NO_OPEN_SUPPORT
Definition: fuse_common.h:279
+
int fuse_req_interrupted(fuse_req_t req)
+
void fuse_session_reset(struct fuse_session *se)
+
void fuse_lowlevel_version(void)
+
int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov, int count)
+
void fuse_reply_none(fuse_req_t req)
+
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
+ + +
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:33
+
#define FUSE_CAP_SPLICE_MOVE
Definition: fuse_common.h:168
+
size_t idx
Definition: fuse_common.h:674
+ +
size_t count
Definition: fuse_common.h:669
+
#define FUSE_CAP_AUTO_INVAL_DATA
Definition: fuse_common.h:219
+
int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent, const char *name, size_t namelen)
+ +
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
+
#define FUSE_CAP_SPLICE_READ
Definition: fuse_common.h:177
+
void fuse_session_unmount(struct fuse_session *se)
+
unsigned int nonseekable
Definition: fuse_common.h:60
+
#define FUSE_OPT_END
Definition: fuse_opt.h:104
+
enum fuse_buf_flags flags
Definition: fuse_common.h:633
+
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
+
void fuse_pollhandle_destroy(struct fuse_pollhandle *ph)
+
unsigned int flush
Definition: fuse_common.h:56
+ +
#define FUSE_CAP_FLOCK_LOCKS
Definition: fuse_common.h:190
+
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
+
char ** argv
Definition: fuse_opt.h:114
+
#define FUSE_CAP_ASYNC_DIO
Definition: fuse_common.h:257
+
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
+
uint64_t generation
Definition: fuse_lowlevel.h:82
+
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
+
int fuse_reply_write(fuse_req_t req, size_t count)
+
void * mem
Definition: fuse_common.h:640
+
#define FUSE_CAP_WRITEBACK_CACHE
Definition: fuse_common.h:266
+
#define FUSE_CAP_POSIX_LOCKS
Definition: fuse_common.h:128
+
#define FUSE_CAP_POSIX_ACL
Definition: fuse_common.h:308
+
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
+ + +
struct fuse_buf buf[1]
Definition: fuse_common.h:684
+ +
#define FUSE_CAP_ATOMIC_O_TRUNC
Definition: fuse_common.h:137
+ +
#define FUSE_CAP_READDIRPLUS
Definition: fuse_common.h:227
+
#define FUSE_CAP_PARALLEL_DIROPS
Definition: fuse_common.h:289
+
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
Definition: buffer.c:22
+
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
Definition: buffer.c:281
+
size_t size
Definition: fuse_common.h:628
+
double entry_timeout
+
fuse_buf_copy_flags
Definition: fuse_common.h:579
+ +
double attr_timeout
Definition: fuse_lowlevel.h:97
+
int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
+ +
int fuse_reply_readlink(fuse_req_t req, const char *link)
+
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
+
int fuse_reply_poll(fuse_req_t req, unsigned revents)
+
void fuse_session_process_buf(struct fuse_session *se, const struct fuse_buf *buf)
+
#define FUSE_CAP_DONT_MASK
Definition: fuse_common.h:152
+
+ + + + diff --git a/doc/html/fuse__lowlevel_8h.html b/doc/html/fuse__lowlevel_8h.html new file mode 100644 index 0000000..506a22a --- /dev/null +++ b/doc/html/fuse__lowlevel_8h.html @@ -0,0 +1,2298 @@ + + + + + + + +libfuse: include/fuse_lowlevel.h File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+ +
+
fuse_lowlevel.h File Reference
+
+
+
#include "fuse_common.h"
+#include <utime.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/uio.h>
+
+

Go to the source code of this file.

+ + + + + + + + +

+Data Structures

struct  fuse_entry_param
 
struct  fuse_ctx
 
struct  fuse_lowlevel_ops
 
+ + + +

+Macros

#define FUSE_ROOT_ID   1
 
+ + + + + + + +

+Typedefs

typedef uint64_t fuse_ino_t
 
typedef struct fuse_req * fuse_req_t
 
typedef void(* fuse_interrupt_func_t) (fuse_req_t req, void *data)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

int fuse_reply_err (fuse_req_t req, int err)
 
void fuse_reply_none (fuse_req_t req)
 
int fuse_reply_entry (fuse_req_t req, const struct fuse_entry_param *e)
 
int fuse_reply_create (fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
 
int fuse_reply_attr (fuse_req_t req, const struct stat *attr, double attr_timeout)
 
int fuse_reply_readlink (fuse_req_t req, const char *link)
 
int fuse_reply_open (fuse_req_t req, const struct fuse_file_info *fi)
 
int fuse_reply_write (fuse_req_t req, size_t count)
 
int fuse_reply_buf (fuse_req_t req, const char *buf, size_t size)
 
int fuse_reply_data (fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
 
int fuse_reply_iov (fuse_req_t req, const struct iovec *iov, int count)
 
int fuse_reply_statfs (fuse_req_t req, const struct statvfs *stbuf)
 
int fuse_reply_xattr (fuse_req_t req, size_t count)
 
int fuse_reply_lock (fuse_req_t req, const struct flock *lock)
 
int fuse_reply_bmap (fuse_req_t req, uint64_t idx)
 
size_t fuse_add_direntry (fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
 
size_t fuse_add_direntry_plus (fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct fuse_entry_param *e, off_t off)
 
int fuse_reply_ioctl_retry (fuse_req_t req, const struct iovec *in_iov, size_t in_count, const struct iovec *out_iov, size_t out_count)
 
int fuse_reply_ioctl (fuse_req_t req, int result, const void *buf, size_t size)
 
int fuse_reply_ioctl_iov (fuse_req_t req, int result, const struct iovec *iov, int count)
 
int fuse_reply_poll (fuse_req_t req, unsigned revents)
 
int fuse_lowlevel_notify_poll (struct fuse_pollhandle *ph)
 
int fuse_lowlevel_notify_inval_inode (struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
 
int fuse_lowlevel_notify_inval_entry (struct fuse_session *se, fuse_ino_t parent, const char *name, size_t namelen)
 
int fuse_lowlevel_notify_delete (struct fuse_session *se, fuse_ino_t parent, fuse_ino_t child, const char *name, size_t namelen)
 
int fuse_lowlevel_notify_store (struct fuse_session *se, fuse_ino_t ino, off_t offset, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
 
int fuse_lowlevel_notify_retrieve (struct fuse_session *se, fuse_ino_t ino, size_t size, off_t offset, void *cookie)
 
void * fuse_req_userdata (fuse_req_t req)
 
const struct fuse_ctxfuse_req_ctx (fuse_req_t req)
 
int fuse_req_getgroups (fuse_req_t req, int size, gid_t list[])
 
void fuse_req_interrupt_func (fuse_req_t req, fuse_interrupt_func_t func, void *data)
 
int fuse_req_interrupted (fuse_req_t req)
 
void fuse_lowlevel_version (void)
 
void fuse_lowlevel_help (void)
 
void fuse_cmdline_help (void)
 
int fuse_parse_cmdline (struct fuse_args *args, struct fuse_cmdline_opts *opts)
 
struct fuse_session * fuse_session_new (struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
 
int fuse_session_mount (struct fuse_session *se, const char *mountpoint)
 
int fuse_session_loop (struct fuse_session *se)
 
int fuse_session_loop_mt_31 (struct fuse_session *se, int clone_fd)
 
void fuse_session_exit (struct fuse_session *se)
 
void fuse_session_reset (struct fuse_session *se)
 
int fuse_session_exited (struct fuse_session *se)
 
void fuse_session_unmount (struct fuse_session *se)
 
void fuse_session_destroy (struct fuse_session *se)
 
int fuse_session_fd (struct fuse_session *se)
 
void fuse_session_process_buf (struct fuse_session *se, const struct fuse_buf *buf)
 
int fuse_session_receive_buf (struct fuse_session *se, struct fuse_buf *buf)
 
+

Detailed Description

+

Low level API

+

IMPORTANT: you should define FUSE_USE_VERSION before including this header. To use the newest API define it to 31 (recommended for any new application).

+ +

Definition in file fuse_lowlevel.h.

+

Macro Definition Documentation

+ +

◆ FUSE_ROOT_ID

+ +
+
+ + + + +
#define FUSE_ROOT_ID   1
+
+

The node ID of the root inode

+ +

Definition at line 43 of file fuse_lowlevel.h.

+ +
+
+

Typedef Documentation

+ +

◆ fuse_ino_t

+ +
+
+ + + + +
typedef uint64_t fuse_ino_t
+
+

Inode number type

+ +

Definition at line 46 of file fuse_lowlevel.h.

+ +
+
+ +

◆ fuse_interrupt_func_t

+ +
+
+ + + + +
typedef void(* fuse_interrupt_func_t) (fuse_req_t req, void *data)
+
+

Callback function for an interrupt

+
Parameters
+ + + +
reqinterrupted request
datauser data
+
+
+ +

Definition at line 1760 of file fuse_lowlevel.h.

+ +
+
+ +

◆ fuse_req_t

+ +
+
+ + + + +
typedef struct fuse_req* fuse_req_t
+
+

Request pointer type

+ +

Definition at line 49 of file fuse_lowlevel.h.

+ +
+
+

Function Documentation

+ +

◆ fuse_add_direntry()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
size_t fuse_add_direntry (fuse_req_t req,
char * buf,
size_t bufsize,
const char * name,
const struct stat * stbuf,
off_t off 
)
+
+

Add a directory entry to the buffer

+

Buffer needs to be large enough to hold the entry. If it's not, then the entry is not filled in but the size of the entry is still returned. The caller can check this by comparing the bufsize parameter with the returned entry size. If the entry size is larger than the buffer size, the operation failed.

+

From the 'stbuf' argument the st_ino field and bits 12-15 of the st_mode field are used. The other fields are ignored.

+

off should be any non-zero value that the filesystem can use to identify the current point in the directory stream. It does not need to be the actual physical position. A value of zero is reserved to mean "from the beginning", and should therefore never be used (the first call to fuse_add_direntry should be passed the offset of the second directory entry).

+
Parameters
+ + + + + + + +
reqrequest handle
bufthe point where the new entry will be added to the buffer
bufsizeremaining size of the buffer
namethe name of the entry
stbufthe file attributes
offthe offset of the next entry
+
+
+
Returns
the space needed for the entry
+ +

Definition at line 267 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_add_direntry_plus()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
size_t fuse_add_direntry_plus (fuse_req_t req,
char * buf,
size_t bufsize,
const char * name,
const struct fuse_entry_parame,
off_t off 
)
+
+

Add a directory entry to the buffer with the attributes

+

See documentation of fuse_add_direntry() for more details.

+
Parameters
+ + + + + + + +
reqrequest handle
bufthe point where the new entry will be added to the buffer
bufsizeremaining size of the buffer
namethe name of the entry
ethe directory entry
offthe offset of the next entry
+
+
+
Returns
the space needed for the entry
+ +

Definition at line 357 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_cmdline_help()

+ +
+
+ + + + + + + + +
void fuse_cmdline_help (void )
+
+

Print available options for fuse_parse_cmdline().

+ +

Definition at line 129 of file helper.c.

+ +
+
+ +

◆ fuse_lowlevel_help()

+ +
+
+ + + + + + + + +
void fuse_lowlevel_help (void )
+
+

Print available low-level options to stdout. This is not an exhaustive list, but includes only those options that may be of interest to an end-user of a file system.

+ +

Definition at line 2611 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_lowlevel_notify_delete()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_lowlevel_notify_delete (struct fuse_session * se,
fuse_ino_t parent,
fuse_ino_t child,
const char * name,
size_t namelen 
)
+
+

This function behaves like fuse_lowlevel_notify_inval_entry() with the following additional effect (at least as of Linux kernel 4.8):

+

If the provided child inode matches the inode that is currently associated with the cached dentry, and if there are any inotify watches registered for the dentry, then the watchers are informed that the dentry has been deleted.

+

To avoid a deadlock this function must not be called while executing a related filesytem operation or while holding a lock that could be needed to execute such an operation (see the description of fuse_lowlevel_notify_inval_entry() for more details).

+

When called correctly, this function will never block.

+

Added in FUSE protocol version 7.18. If the kernel does not support this (or a newer) version, the function will return -ENOSYS and do nothing.

+
Parameters
+ + + + + + +
sethe session object
parentinode number
childinode number
namefile name
namelenstrlen() of file name
+
+
+
Returns
zero for success, -errno for failure
+ +

Definition at line 2187 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_lowlevel_notify_inval_entry()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_lowlevel_notify_inval_entry (struct fuse_session * se,
fuse_ino_t parent,
const char * name,
size_t namelen 
)
+
+

Notify to invalidate parent attributes and the dentry matching parent/name

+

To avoid a deadlock this function must not be called while executing a related filesytem operation or while holding a lock that could be needed to execute such an operation. As of kernel 4.18, a "related operation" is a lookup(), symlink(), mknod(), mkdir(), unlink(), rename(), link() or create() request for the parent, and a setattr(), unlink(), rmdir(), rename(), setxattr(), removexattr(), readdir() or readdirplus() request for the inode itself.

+

When called correctly, this function will never block.

+

Added in FUSE protocol version 7.12. If the kernel does not support this (or a newer) version, the function will return -ENOSYS and do nothing.

+
Parameters
+ + + + + +
sethe session object
parentinode number
namefile name
namelenstrlen() of file name
+
+
+
Returns
zero for success, -errno for failure
+ +

Definition at line 2163 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_lowlevel_notify_inval_inode()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_lowlevel_notify_inval_inode (struct fuse_session * se,
fuse_ino_t ino,
off_t off,
off_t len 
)
+
+

Notify to invalidate cache for an inode.

+

Added in FUSE protocol version 7.12. If the kernel does not support this (or a newer) version, the function will return -ENOSYS and do nothing.

+

If the filesystem has writeback caching enabled, invalidating an inode will first trigger a writeback of all dirty pages. The call will block until all writeback requests have completed and the inode has been invalidated. It will, however, not wait for completion of pending writeback requests that have been issued before.

+

If there are no dirty pages, this function will never block.

+
Parameters
+ + + + + +
sethe session object
inothe inode number
offthe offset in the inode where to start invalidating or negative to invalidate attributes only
lenthe amount of cache to invalidate or 0 for all
+
+
+
Returns
zero for success, -errno for failure
+ +

Definition at line 2141 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_lowlevel_notify_poll()

+ +
+
+ + + + + + + + +
int fuse_lowlevel_notify_poll (struct fuse_pollhandle * ph)
+
+

Notify IO readiness event

+

For more information, please read comment for poll operation.

+
Parameters
+ + +
phpoll handle to notify IO readiness event for
+
+
+ +

Definition at line 2124 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_lowlevel_notify_retrieve()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_lowlevel_notify_retrieve (struct fuse_session * se,
fuse_ino_t ino,
size_t size,
off_t offset,
void * cookie 
)
+
+

Retrieve data from the kernel buffers

+

Retrieve data in the kernel buffers belonging to the given inode. If successful then the retrieve_reply() method will be called with the returned data.

+

Only present pages are returned in the retrieve reply. Retrieving stops when it finds a non-present page and only data prior to that is returned.

+

If this function returns an error, then the retrieve will not be completed and no reply will be sent.

+

This function doesn't change the dirty state of pages in the kernel buffer. For dirty pages the write() method will be called regardless of having been retrieved previously.

+

Added in FUSE protocol version 7.15. If the kernel does not support this (or a newer) version, the function will return -ENOSYS and do nothing.

+
Parameters
+ + + + + + +
sethe session object
inothe inode number
sizethe number of bytes to retrieve
offsetthe starting offset into the file to retrieve from
cookieuser data to supply to the reply callback
+
+
+
Returns
zero for success, -errno for failure
+ +

Definition at line 2293 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_lowlevel_notify_store()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_lowlevel_notify_store (struct fuse_session * se,
fuse_ino_t ino,
off_t offset,
struct fuse_bufvecbufv,
enum fuse_buf_copy_flags flags 
)
+
+

Store data to the kernel buffers

+

Synchronously store data in the kernel buffers belonging to the given inode. The stored data is marked up-to-date (no read will be performed against it, unless it's invalidated or evicted from the cache).

+

If the stored data overflows the current file size, then the size is extended, similarly to a write(2) on the filesystem.

+

If this function returns an error, then the store wasn't fully completed, but it may have been partially completed.

+

Added in FUSE protocol version 7.15. If the kernel does not support this (or a newer) version, the function will return -ENOSYS and do nothing.

+
Parameters
+ + + + + + +
sethe session object
inothe inode number
offsetthe starting offset into the file to store to
bufvbuffer vector
flagsflags controlling the copy
+
+
+
Returns
zero for success, -errno for failure
+ +

Definition at line 2213 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_lowlevel_version()

+ +
+
+ + + + + + + + +
void fuse_lowlevel_version (void )
+
+

Print low-level version information to stdout.

+ +

Definition at line 2604 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_parse_cmdline()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_parse_cmdline (struct fuse_argsargs,
struct fuse_cmdline_opts * opts 
)
+
+

Utility function to parse common options for simple file systems using the low-level API. A help text that describes the available options can be printed with fuse_cmdline_help. A single non-option argument is treated as the mountpoint. Multiple non-option arguments will result in an error.

+

If neither -o subtype= or -o fsname= options are given, a new subtype option will be added and set to the basename of the program (the fsname will remain unset, and then defaults to "fuse").

+

Known options will be removed from args, unknown options will remain.

+
Parameters
+ + + +
argsargument vector (input+output)
optsoutput argument for parsed options
+
+
+
Returns
0 on success, -1 on failure
+ +

Definition at line 202 of file helper.c.

+ +
+
+ +

◆ fuse_reply_attr()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_reply_attr (fuse_req_t req,
const struct stat * attr,
double attr_timeout 
)
+
+

Reply with attributes

+

Possible requests: getattr, setattr

+
Parameters
+ + + + +
reqrequest handle
attrthe attributes
attr_timeoutvalidity timeout (in seconds) for the attributes
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 431 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_bmap()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_bmap (fuse_req_t req,
uint64_t idx 
)
+
+

Reply with block index

+

Possible requests: bmap

+
Parameters
+ + + +
reqrequest handle
idxblock index within device
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 881 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_buf()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_reply_buf (fuse_req_t req,
const char * buf,
size_t size 
)
+
+

Reply with data

+

Possible requests: read, readdir, getxattr, listxattr

+
Parameters
+ + + + +
reqrequest handle
bufbuffer containing data
sizethe size of data in bytes
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 470 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_create()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_reply_create (fuse_req_t req,
const struct fuse_entry_parame,
const struct fuse_file_infofi 
)
+
+

Reply with a directory entry and open parameters

+

currently the following members of 'fi' are used: fh, direct_io, keep_cache

+

Possible requests: create

+

Side effects: increments the lookup count on success

+
Parameters
+ + + + +
reqrequest handle
ethe entry parameters
fifile information
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 415 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_data()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_reply_data (fuse_req_t req,
struct fuse_bufvecbufv,
enum fuse_buf_copy_flags flags 
)
+
+

Reply with data copied/moved from buffer(s)

+

Zero copy data transfer ("splicing") will be used under the following circumstances:

+
    +
  1. FUSE_CAP_SPLICE_WRITE is set in fuse_conn_info.want, and
  2. +
  3. the kernel supports splicing from the fuse device (FUSE_CAP_SPLICE_WRITE is set in fuse_conn_info.capable), and
  4. +
  5. flags does not contain FUSE_BUF_NO_SPLICE
  6. +
  7. The amount of data that is provided in file-descriptor backed buffers (i.e., buffers for which bufv[n].flags == FUSE_BUF_FD) is at least twice the page size.
  8. +
+

In order for SPLICE_F_MOVE to be used, the following additional conditions have to be fulfilled:

+
    +
  1. FUSE_CAP_SPLICE_MOVE is set in fuse_conn_info.want, and
  2. +
  3. the kernel supports it (i.e, FUSE_CAP_SPLICE_MOVE is set in fuse_conn_info.capable), and
  4. +
  5. flags contains FUSE_BUF_SPLICE_MOVE
  6. +
+

Note that, if splice is used, the data is actually spliced twice: once into a temporary pipe (to prepend header data), and then again into the kernel. If some of the provided buffers are memory-backed, the data in them is copied in step one and spliced in step two.

+

The FUSE_BUF_SPLICE_FORCE_SPLICE and FUSE_BUF_SPLICE_NONBLOCK flags are silently ignored.

+

Possible requests: read, readdir, getxattr, listxattr

+

Side effects: when used to return data from a readdirplus() (but not readdir()) call, increments the lookup count of each returned entry by one on success.

+
Parameters
+ + + + +
reqrequest handle
bufvbuffer vector
flagsflags controlling the copy
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 820 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_entry()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_entry (fuse_req_t req,
const struct fuse_entry_parame 
)
+
+

Reply with a directory entry

+

Possible requests: lookup, mknod, mkdir, symlink, link

+

Side effects: increments the lookup count on success

+
Parameters
+ + + +
reqrequest handle
ethe entry parameters
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 399 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_err()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_err (fuse_req_t req,
int err 
)
+
+

Reply with an error code or success.

+

Possible requests: all except forget

+

Whereever possible, error codes should be chosen from the list of documented error conditions in the corresponding system calls manpage.

+

An error code of ENOSYS is sometimes treated specially. This is indicated in the documentation of the affected handler functions.

+

The following requests may be answered with a zero error code: unlink, rmdir, rename, flush, release, fsync, fsyncdir, setxattr, removexattr, setlk.

+
Parameters
+ + + +
reqrequest handle
errthe positive error value, or zero for success
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 312 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_ioctl()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_reply_ioctl (fuse_req_t req,
int result,
const void * buf,
size_t size 
)
+
+

Reply to finish ioctl

+

Possible requests: ioctl

+
Parameters
+ + + + + +
reqrequest handle
resultresult to be passed to the caller
bufbuffer containing output data
sizelength of output data
+
+
+ +

Definition at line 979 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_ioctl_iov()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_reply_ioctl_iov (fuse_req_t req,
int result,
const struct iovec * iov,
int count 
)
+
+

Reply to finish ioctl with iov buffer

+

Possible requests: ioctl

+
Parameters
+ + + + + +
reqrequest handle
resultresult to be passed to the caller
iovthe vector containing the data
countthe size of vector
+
+
+ +

Definition at line 1000 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_ioctl_retry()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_reply_ioctl_retry (fuse_req_t req,
const struct iovec * in_iov,
size_t in_count,
const struct iovec * out_iov,
size_t out_count 
)
+
+

Reply to ask for data fetch and output buffer preparation. ioctl will be retried with the specified input data fetched and output buffer prepared.

+

Possible requests: ioctl

+
Parameters
+ + + + + + +
reqrequest handle
in_ioviovec specifying data to fetch from the caller
in_countnumber of entries in in_iov
out_ioviovec specifying addresses to write output to
out_countnumber of entries in out_iov
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 909 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_iov()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_reply_iov (fuse_req_t req,
const struct iovec * iov,
int count 
)
+
+

Reply with data vector

+

Possible requests: read, readdir, getxattr, listxattr

+
Parameters
+ + + + +
reqrequest handle
iovthe vector containing the data
countthe size of vector
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 246 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_lock()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_lock (fuse_req_t req,
const struct flock * lock 
)
+
+

Reply with file lock information

+

Possible requests: getlk

+
Parameters
+ + + +
reqrequest handle
lockthe lock information
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 864 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_none()

+ +
+
+ + + + + + + + +
void fuse_reply_none (fuse_req_t req)
+
+

Don't send reply

+

Possible requests: forget forget_multi retrieve_reply

+
Parameters
+ + +
reqrequest handle
+
+
+ +

Definition at line 317 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_open()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_open (fuse_req_t req,
const struct fuse_file_infofi 
)
+
+

Reply with open parameters

+

currently the following members of 'fi' are used: fh, direct_io, keep_cache

+

Possible requests: open, opendir

+
Parameters
+ + + +
reqrequest handle
fifile information
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 451 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_poll()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_poll (fuse_req_t req,
unsigned revents 
)
+
+

Reply with poll result event mask

+
Parameters
+ + + +
reqrequest handle
reventspoll result event mask
+
+
+ +

Definition at line 1024 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_readlink()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_readlink (fuse_req_t req,
const char * link 
)
+
+

Reply with the contents of a symbolic link

+

Possible requests: readlink

+
Parameters
+ + + +
reqrequest handle
linksymbolic link contents
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 446 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_statfs()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_statfs (fuse_req_t req,
const struct statvfs * stbuf 
)
+
+

Reply with filesystem statistics

+

Possible requests: statfs

+
Parameters
+ + + +
reqrequest handle
stbuffilesystem statistics
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 842 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_write()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_write (fuse_req_t req,
size_t count 
)
+
+

Reply with number of bytes written

+

Possible requests: write

+
Parameters
+ + + +
reqrequest handle
countthe number of bytes written
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 460 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_reply_xattr()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_reply_xattr (fuse_req_t req,
size_t count 
)
+
+

Reply with needed buffer size

+

Possible requests: getxattr, listxattr

+
Parameters
+ + + +
reqrequest handle
countthe buffer size needed in bytes
+
+
+
Returns
zero for success, -errno for failure to send reply
+ +

Definition at line 854 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_req_ctx()

+ +
+
+ + + + + + + + +
const struct fuse_ctx* fuse_req_ctx (fuse_req_t req)
+
+

Get the context from the request

+

The pointer returned by this function will only be valid for the request's lifetime

+
Parameters
+ + +
reqrequest handle
+
+
+
Returns
the context structure
+ +

Definition at line 2343 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_req_getgroups()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_req_getgroups (fuse_req_t req,
int size,
gid_t list[] 
)
+
+

Get the current supplementary group IDs for the specified request

+

Similar to the getgroups(2) system call, except the return value is always the total number of group IDs, even if it is larger than the specified size.

+

The current fuse kernel module in linux (as of 2.6.30) doesn't pass the group list to userspace, hence this function needs to parse "/proc/$TID/task/$TID/status" to get the group IDs.

+

This feature may not be supported on all operating systems. In such a case this function will return -ENOSYS.

+
Parameters
+ + + + +
reqrequest handle
sizesize of given array
listarray of group IDs to be filled in
+
+
+
Returns
the total number of supplementary group IDs or -errno on failure
+ +

Definition at line 3030 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_req_interrupt_func()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void fuse_req_interrupt_func (fuse_req_t req,
fuse_interrupt_func_t func,
void * data 
)
+
+

Register/unregister callback for an interrupt

+

If an interrupt has already happened, then the callback function is called from within this function, hence it's not possible for interrupts to be lost.

+
Parameters
+ + + + +
reqrequest handle
functhe callback function or NULL for unregister
datauser data passed to the callback function
+
+
+ +

Definition at line 2348 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_req_interrupted()

+ +
+
+ + + + + + + + +
int fuse_req_interrupted (fuse_req_t req)
+
+

Check if a request has already been interrupted

+
Parameters
+ + +
reqrequest handle
+
+
+
Returns
1 if the request has been interrupted, 0 otherwise
+ +

Definition at line 2361 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_req_userdata()

+ +
+
+ + + + + + + + +
void* fuse_req_userdata (fuse_req_t req)
+
+

Get the userdata from the request

+
Parameters
+ + +
reqrequest handle
+
+
+
Returns
the user data passed to fuse_session_new()
+ +

Definition at line 2338 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_destroy()

+ +
+
+ + + + + + + + +
void fuse_session_destroy (struct fuse_session * se)
+
+

Destroy a session

+
Parameters
+ + +
sethe session
+
+
+ +

Definition at line 2621 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_exit()

+ +
+
+ + + + + + + + +
void fuse_session_exit (struct fuse_session * se)
+
+

Flag a session as terminated.

+

This function is invoked by the POSIX signal handlers, when registered using fuse_set_signal_handlers(). It will cause any running event loops to terminate on the next opportunity.

+
Parameters
+ + +
sethe session
+
+
+ +

Definition at line 3037 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_exited()

+ +
+
+ + + + + + + + +
int fuse_session_exited (struct fuse_session * se)
+
+

Query the terminated flag of a session

+
Parameters
+ + +
sethe session
+
+
+
Returns
1 if exited, 0 if not exited
+ +

Definition at line 3048 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_fd()

+ +
+
+ + + + + + + + +
int fuse_session_fd (struct fuse_session * se)
+
+

Return file descriptor for communication with kernel.

+

The file selector can be used to integrate FUSE with a custom event loop. Whenever data is available for reading on the provided fd, the event loop should call fuse_session_receive_buf followed by fuse_session_process_buf to process the request.

+

The returned file descriptor is valid until fuse_session_unmount is called.

+
Parameters
+ + +
sethe session
+
+
+
Returns
a file descriptor
+ +

Definition at line 2953 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_loop()

+ +
+
+ + + + + + + + +
int fuse_session_loop (struct fuse_session * se)
+
+

Enter a single threaded, blocking event loop.

+

When the event loop terminates because the connection to the FUSE kernel module has been closed, this function returns zero. This happens when the filesystem is unmounted regularly (by the filesystem owner or root running the umount(8) or fusermount(1) command), or if connection is explicitly severed by writing 1 to theabort file in /sys/fs/fuse/connections/NNN. The only way to distinguish between these two conditions is to check if the filesystem is still mounted after the session loop returns.

+

When some error occurs during request processing, the function returns a negated errno(3) value.

+

If the loop has been terminated because of a signal handler installed by fuse_set_signal_handlers(), this function returns the (positive) signal value that triggered the exit.

+
Parameters
+ + +
sethe session
+
+
+
Returns
0, -errno, or a signal value
+ +

Definition at line 19 of file fuse_loop.c.

+ +
+
+ +

◆ fuse_session_loop_mt_31()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_session_loop_mt_31 (struct fuse_session * se,
int clone_fd 
)
+
+

Enter a multi-threaded event loop.

+

For a description of the return value and the conditions when the event loop exits, refer to the documentation of fuse_session_loop().

+
Parameters
+ + + +
sethe session
configsession loop configuration
+
+
+
Returns
see fuse_session_loop()
+ +

Definition at line 356 of file fuse_loop_mt.c.

+ +
+
+ +

◆ fuse_session_mount()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_session_mount (struct fuse_session * se,
const char * mountpoint 
)
+
+

Mount a FUSE file system.

+
Parameters
+ + + +
mountpointthe mount point path
sesession object
+
+
+
Returns
0 on success, -1 on failure.
+ +

Definition at line 2903 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_new()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
struct fuse_session* fuse_session_new (struct fuse_argsargs,
const struct fuse_lowlevel_opsop,
size_t op_size,
void * userdata 
)
+
+

Create a low level session.

+

Returns a session structure suitable for passing to fuse_session_mount() and fuse_session_loop().

+

This function accepts most file-system independent mount options (like context, nodev, ro - see mount(8)), as well as the general fuse mount options listed in mount.fuse(8) (e.g. -o allow_root and -o default_permissions, but not -o use_ino). Instead of -o debug, debugging may also enabled with -d or --debug.

+

If not all options are known, an error message is written to stderr and the function returns NULL.

+

Option parsing skips argv[0], which is assumed to contain the program name. To prevent accidentally passing an option in argv[0], this element must always be present (even if no options are specified). It may be set to the empty string ('\0') if no reasonable value can be provided.

+
Parameters
+ + + + + +
argsargument vector
opthe (low-level) filesystem operations
op_sizesizeof(struct fuse_lowlevel_ops)
userdatauser data
+
+
+
Returns
the fuse session on success, NULL on failure
+ +

Definition at line 2809 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_process_buf()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void fuse_session_process_buf (struct fuse_session * se,
const struct fuse_bufbuf 
)
+
+

Process a raw request supplied in a generic buffer

+

The fuse_buf may contain a memory buffer or a pipe file descriptor.

+
Parameters
+ + + +
sethe session
bufthe fuse_buf containing the request
+
+
+ +

Definition at line 2448 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_receive_buf()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_session_receive_buf (struct fuse_session * se,
struct fuse_bufbuf 
)
+
+

Read a raw request from the kernel into the supplied buffer.

+

Depending on file system options, system capabilities, and request size the request is either read into a memory buffer or spliced into a temporary pipe.

+
Parameters
+ + + +
sethe session
bufthe fuse_buf to store the request in
+
+
+
Returns
the actual size of the raw request, or -errno on error
+ +

Definition at line 2648 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_reset()

+ +
+
+ + + + + + + + +
void fuse_session_reset (struct fuse_session * se)
+
+

Reset the terminated flag of a session

+
Parameters
+ + +
sethe session
+
+
+ +

Definition at line 3042 of file fuse_lowlevel.c.

+ +
+
+ +

◆ fuse_session_unmount()

+ +
+
+ + + + + + + + +
void fuse_session_unmount (struct fuse_session * se)
+
+

Ensure that file system is unmounted.

+

In regular operation, the file system is typically unmounted by the user calling umount(8) or fusermount(1), which then terminates the FUSE session loop. However, the session loop may also terminate as a result of an explicit call to fuse_session_exit() (e.g. by a signal handler installed by fuse_set_signal_handler()). In this case the filesystem remains mounted, but any attempt to access it will block (while the filesystem process is still running) or give an ESHUTDOWN error (after the filesystem process has terminated).

+

If the communication channel with the FUSE kernel module is still open (i.e., if the session loop was terminated by an explicit call to fuse_session_exit()), this function will close it and unmount the filesystem. If the communication channel has been closed by the kernel, this method will do (almost) nothing.

+

NOTE: The above semantics mean that if the connection to the kernel is terminated via the /sys/fs/fuse/connections/NNN/abort file, this method will not unmount the filesystem.

+
Parameters
+ + +
sethe session
+
+
+ +

Definition at line 2958 of file fuse_lowlevel.c.

+ +
+
+
+ + + + diff --git a/doc/html/fuse__lowlevel_8h_source.html b/doc/html/fuse__lowlevel_8h_source.html new file mode 100644 index 0000000..f9df461 --- /dev/null +++ b/doc/html/fuse__lowlevel_8h_source.html @@ -0,0 +1,131 @@ + + + + + + + +libfuse: include/fuse_lowlevel.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_lowlevel.h
+
+
+Go to the documentation of this file.
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU LGPLv2.
6  See the file COPYING.LIB.
7 */
8 
9 #ifndef FUSE_LOWLEVEL_H_
10 #define FUSE_LOWLEVEL_H_
11 
21 #ifndef FUSE_USE_VERSION
22 #error FUSE_USE_VERSION not defined
23 #endif
24 
25 #include "fuse_common.h"
26 
27 #include <utime.h>
28 #include <fcntl.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/statvfs.h>
32 #include <sys/uio.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /* ----------------------------------------------------------- *
39  * Miscellaneous definitions *
40  * ----------------------------------------------------------- */
41 
43 #define FUSE_ROOT_ID 1
44 
46 typedef uint64_t fuse_ino_t;
47 
49 typedef struct fuse_req *fuse_req_t;
50 
56 struct fuse_session;
57 
67  fuse_ino_t ino;
68 
82  uint64_t generation;
83 
91  struct stat attr;
92 
97  double attr_timeout;
98 
104 };
105 
114 struct fuse_ctx {
116  uid_t uid;
117 
119  gid_t gid;
120 
122  pid_t pid;
123 
125  mode_t umask;
126 };
127 
128 struct fuse_forget_data {
129  fuse_ino_t ino;
130  uint64_t nlookup;
131 };
132 
133 /* 'to_set' flags in setattr */
134 #define FUSE_SET_ATTR_MODE (1 << 0)
135 #define FUSE_SET_ATTR_UID (1 << 1)
136 #define FUSE_SET_ATTR_GID (1 << 2)
137 #define FUSE_SET_ATTR_SIZE (1 << 3)
138 #define FUSE_SET_ATTR_ATIME (1 << 4)
139 #define FUSE_SET_ATTR_MTIME (1 << 5)
140 #define FUSE_SET_ATTR_ATIME_NOW (1 << 7)
141 #define FUSE_SET_ATTR_MTIME_NOW (1 << 8)
142 #define FUSE_SET_ATTR_CTIME (1 << 10)
143 
144 /* ----------------------------------------------------------- *
145  * Request methods and replies *
146  * ----------------------------------------------------------- */
147 
192  void (*init) (void *userdata, struct fuse_conn_info *conn);
193 
205  void (*destroy) (void *userdata);
206 
218  void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
219 
256  void (*forget) (fuse_req_t req, fuse_ino_t ino, uint64_t nlookup);
257 
277  void (*getattr) (fuse_req_t req, fuse_ino_t ino,
278  struct fuse_file_info *fi);
279 
308  void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
309  int to_set, struct fuse_file_info *fi);
310 
321  void (*readlink) (fuse_req_t req, fuse_ino_t ino);
322 
339  void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
340  mode_t mode, dev_t rdev);
341 
354  void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
355  mode_t mode);
356 
372  void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
373 
389  void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
390 
403  void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
404  const char *name);
405 
435  void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
436  fuse_ino_t newparent, const char *newname,
437  unsigned int flags);
438 
451  void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
452  const char *newname);
453 
510  void (*open) (fuse_req_t req, fuse_ino_t ino,
511  struct fuse_file_info *fi);
512 
538  void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
539  struct fuse_file_info *fi);
540 
567  void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
568  size_t size, off_t off, struct fuse_file_info *fi);
569 
604  void (*flush) (fuse_req_t req, fuse_ino_t ino,
605  struct fuse_file_info *fi);
606 
631  void (*release) (fuse_req_t req, fuse_ino_t ino,
632  struct fuse_file_info *fi);
633 
653  void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
654  struct fuse_file_info *fi);
655 
677  void (*opendir) (fuse_req_t req, fuse_ino_t ino,
678  struct fuse_file_info *fi);
679 
707  void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
708  struct fuse_file_info *fi);
709 
726  void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
727  struct fuse_file_info *fi);
728 
751  void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
752  struct fuse_file_info *fi);
753 
764  void (*statfs) (fuse_req_t req, fuse_ino_t ino);
765 
777  void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
778  const char *value, size_t size, int flags);
779 
808  void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
809  size_t size);
810 
839  void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
840 
856  void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
857 
878  void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
879 
907  void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
908  mode_t mode, struct fuse_file_info *fi);
909 
922  void (*getlk) (fuse_req_t req, fuse_ino_t ino,
923  struct fuse_file_info *fi, struct flock *lock);
924 
947  void (*setlk) (fuse_req_t req, fuse_ino_t ino,
948  struct fuse_file_info *fi,
949  struct flock *lock, int sleep);
950 
971  void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize,
972  uint64_t idx);
973 
999  void (*ioctl) (fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
1000  struct fuse_file_info *fi, unsigned flags,
1001  const void *in_buf, size_t in_bufsz, size_t out_bufsz);
1002 
1032  void (*poll) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
1033  struct fuse_pollhandle *ph);
1034 
1062  void (*write_buf) (fuse_req_t req, fuse_ino_t ino,
1063  struct fuse_bufvec *bufv, off_t off,
1064  struct fuse_file_info *fi);
1065 
1078  void (*retrieve_reply) (fuse_req_t req, void *cookie, fuse_ino_t ino,
1079  off_t offset, struct fuse_bufvec *bufv);
1080 
1092  void (*forget_multi) (fuse_req_t req, size_t count,
1093  struct fuse_forget_data *forgets);
1094 
1110  void (*flock) (fuse_req_t req, fuse_ino_t ino,
1111  struct fuse_file_info *fi, int op);
1112 
1133  void (*fallocate) (fuse_req_t req, fuse_ino_t ino, int mode,
1134  off_t offset, off_t length, struct fuse_file_info *fi);
1135 
1161  void (*readdirplus) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
1162  struct fuse_file_info *fi);
1163 
1194  void (*copy_file_range) (fuse_req_t req, fuse_ino_t ino_in,
1195  off_t off_in, struct fuse_file_info *fi_in,
1196  fuse_ino_t ino_out, off_t off_out,
1197  struct fuse_file_info *fi_out, size_t len,
1198  int flags);
1199 };
1200 
1222 int fuse_reply_err(fuse_req_t req, int err);
1223 
1234 void fuse_reply_none(fuse_req_t req);
1235 
1249 int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e);
1250 
1268 int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
1269  const struct fuse_file_info *fi);
1270 
1282 int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
1283  double attr_timeout);
1284 
1295 int fuse_reply_readlink(fuse_req_t req, const char *link);
1296 
1310 int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi);
1311 
1322 int fuse_reply_write(fuse_req_t req, size_t count);
1323 
1335 int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size);
1336 
1380 int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv,
1381  enum fuse_buf_copy_flags flags);
1382 
1394 int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count);
1395 
1406 int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf);
1407 
1418 int fuse_reply_xattr(fuse_req_t req, size_t count);
1419 
1430 int fuse_reply_lock(fuse_req_t req, const struct flock *lock);
1431 
1442 int fuse_reply_bmap(fuse_req_t req, uint64_t idx);
1443 
1444 /* ----------------------------------------------------------- *
1445  * Filling a buffer in readdir *
1446  * ----------------------------------------------------------- */
1447 
1475 size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize,
1476  const char *name, const struct stat *stbuf,
1477  off_t off);
1478 
1492 size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize,
1493  const char *name,
1494  const struct fuse_entry_param *e, off_t off);
1495 
1511 int fuse_reply_ioctl_retry(fuse_req_t req,
1512  const struct iovec *in_iov, size_t in_count,
1513  const struct iovec *out_iov, size_t out_count);
1514 
1526 int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size);
1527 
1539 int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov,
1540  int count);
1541 
1548 int fuse_reply_poll(fuse_req_t req, unsigned revents);
1549 
1550 /* ----------------------------------------------------------- *
1551  * Notification *
1552  * ----------------------------------------------------------- */
1553 
1561 int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph);
1562 
1586 int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino,
1587  off_t off, off_t len);
1588 
1614 int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent,
1615  const char *name, size_t namelen);
1616 
1645 int fuse_lowlevel_notify_delete(struct fuse_session *se,
1646  fuse_ino_t parent, fuse_ino_t child,
1647  const char *name, size_t namelen);
1648 
1674 int fuse_lowlevel_notify_store(struct fuse_session *se, fuse_ino_t ino,
1675  off_t offset, struct fuse_bufvec *bufv,
1676  enum fuse_buf_copy_flags flags);
1706 int fuse_lowlevel_notify_retrieve(struct fuse_session *se, fuse_ino_t ino,
1707  size_t size, off_t offset, void *cookie);
1708 
1709 
1710 /* ----------------------------------------------------------- *
1711  * Utility functions *
1712  * ----------------------------------------------------------- */
1713 
1720 void *fuse_req_userdata(fuse_req_t req);
1721 
1731 const struct fuse_ctx *fuse_req_ctx(fuse_req_t req);
1732 
1752 int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]);
1753 
1760 typedef void (*fuse_interrupt_func_t)(fuse_req_t req, void *data);
1761 
1773 void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func,
1774  void *data);
1775 
1782 int fuse_req_interrupted(fuse_req_t req);
1783 
1784 
1785 /* ----------------------------------------------------------- *
1786  * Inquiry functions *
1787  * ----------------------------------------------------------- */
1788 
1792 void fuse_lowlevel_version(void);
1793 
1799 void fuse_lowlevel_help(void);
1800 
1804 void fuse_cmdline_help(void);
1805 
1806 /* ----------------------------------------------------------- *
1807  * Filesystem setup & teardown *
1808  * ----------------------------------------------------------- */
1809 
1810 struct fuse_cmdline_opts {
1811  int singlethread;
1812  int foreground;
1813  int debug;
1814  int nodefault_subtype;
1815  char *mountpoint;
1816  int show_version;
1817  int show_help;
1818  int clone_fd;
1819  unsigned int max_idle_threads;
1820 };
1821 
1840 int fuse_parse_cmdline(struct fuse_args *args,
1841  struct fuse_cmdline_opts *opts);
1842 
1871 struct fuse_session *fuse_session_new(struct fuse_args *args,
1872  const struct fuse_lowlevel_ops *op,
1873  size_t op_size, void *userdata);
1874 
1883 int fuse_session_mount(struct fuse_session *se, const char *mountpoint);
1884 
1907 int fuse_session_loop(struct fuse_session *se);
1908 
1920 #if FUSE_USE_VERSION < 32
1921 int fuse_session_loop_mt_31(struct fuse_session *se, int clone_fd);
1922 #define fuse_session_loop_mt(se, clone_fd) fuse_session_loop_mt_31(se, clone_fd)
1923 #else
1924 int fuse_session_loop_mt(struct fuse_session *se, struct fuse_loop_config *config);
1925 #endif
1926 
1936 void fuse_session_exit(struct fuse_session *se);
1937 
1943 void fuse_session_reset(struct fuse_session *se);
1944 
1951 int fuse_session_exited(struct fuse_session *se);
1952 
1977 void fuse_session_unmount(struct fuse_session *se);
1978 
1984 void fuse_session_destroy(struct fuse_session *se);
1985 
1986 /* ----------------------------------------------------------- *
1987  * Custom event loop support *
1988  * ----------------------------------------------------------- */
1989 
2004 int fuse_session_fd(struct fuse_session *se);
2005 
2014 void fuse_session_process_buf(struct fuse_session *se,
2015  const struct fuse_buf *buf);
2016 
2028 int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf);
2029 
2030 #ifdef __cplusplus
2031 }
2032 #endif
2033 
2034 #endif /* FUSE_LOWLEVEL_H_ */
void fuse_session_destroy(struct fuse_session *se)
+
int fuse_reply_err(fuse_req_t req, int err)
+
size_t off
Definition: fuse_common.h:679
+
int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf)
+
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
+
void fuse_session_exit(struct fuse_session *se)
+
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
+
int fuse_lowlevel_notify_retrieve(struct fuse_session *se, fuse_ino_t ino, size_t size, off_t offset, void *cookie)
+ +
int fuse_lowlevel_notify_delete(struct fuse_session *se, fuse_ino_t parent, fuse_ino_t child, const char *name, size_t namelen)
+
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
+
void fuse_lowlevel_help(void)
+
size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct fuse_entry_param *e, off_t off)
+
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
+
int fuse_session_fd(struct fuse_session *se)
+
const struct fuse_ctx * fuse_req_ctx(fuse_req_t req)
+
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
+
int fuse_reply_ioctl_retry(fuse_req_t req, const struct iovec *in_iov, size_t in_count, const struct iovec *out_iov, size_t out_count)
+
mode_t umask
+
void(* fuse_interrupt_func_t)(fuse_req_t req, void *data)
+
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
+
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
+
struct stat attr
Definition: fuse_lowlevel.h:91
+
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
+
void * fuse_req_userdata(fuse_req_t req)
+
int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, off_t off, off_t len)
+ +
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
+
int fuse_session_loop_mt_31(struct fuse_session *se, int clone_fd)
Definition: fuse_loop_mt.c:356
+
Definition: fuse_lowlevel.h:59
+
fuse_ino_t ino
Definition: fuse_lowlevel.h:67
+
int fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts)
Definition: helper.c:202
+
int fuse_reply_xattr(fuse_req_t req, size_t count)
+ +
void fuse_cmdline_help(void)
Definition: helper.c:129
+
int fuse_session_exited(struct fuse_session *se)
+
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
+
int fuse_lowlevel_notify_store(struct fuse_session *se, fuse_ino_t ino, off_t offset, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags)
+ + +
int fuse_reply_lock(fuse_req_t req, const struct flock *lock)
+
int fuse_req_interrupted(fuse_req_t req)
+
void fuse_session_reset(struct fuse_session *se)
+
void fuse_lowlevel_version(void)
+
int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov, int count)
+
void fuse_reply_none(fuse_req_t req)
+
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
+ + + + +
size_t count
Definition: fuse_common.h:669
+
int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent, const char *name, size_t namelen)
+
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
+
void fuse_session_unmount(struct fuse_session *se)
+
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
+
unsigned int flush
Definition: fuse_common.h:56
+
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
+
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void *data)
+
uint64_t generation
Definition: fuse_lowlevel.h:82
+
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, const struct fuse_file_info *fi)
+
int fuse_reply_write(fuse_req_t req, size_t count)
+
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
+ + + +
double entry_timeout
+
fuse_buf_copy_flags
Definition: fuse_common.h:579
+
double attr_timeout
Definition: fuse_lowlevel.h:97
+
int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
+ +
int fuse_reply_readlink(fuse_req_t req, const char *link)
+
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
+
int fuse_reply_poll(fuse_req_t req, unsigned revents)
+
void fuse_session_process_buf(struct fuse_session *se, const struct fuse_buf *buf)
+
+ + + + diff --git a/doc/html/fuse__misc_8h_source.html b/doc/html/fuse__misc_8h_source.html new file mode 100644 index 0000000..74bcf16 --- /dev/null +++ b/doc/html/fuse__misc_8h_source.html @@ -0,0 +1,56 @@ + + + + + + + +libfuse: lib/fuse_misc.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_misc.h
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU LGPLv2.
6  See the file COPYING.LIB
7 */
8 
9 #include <pthread.h>
10 
11 /*
12  Versioned symbols cannot be used in some cases because it
13  - confuse the dynamic linker in uClibc
14  - not supported on MacOSX (in MachO binary format)
15 */
16 #if (!defined(__UCLIBC__) && !defined(__APPLE__))
17 #define FUSE_SYMVER(x) __asm__(x)
18 #else
19 #define FUSE_SYMVER(x)
20 #endif
21 
22 #ifndef USE_UCLIBC
23 #define fuse_mutex_init(mut) pthread_mutex_init(mut, NULL)
24 #else
25 /* Is this hack still needed? */
26 static inline void fuse_mutex_init(pthread_mutex_t *mut)
27 {
28  pthread_mutexattr_t attr;
29  pthread_mutexattr_init(&attr);
30  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
31  pthread_mutex_init(mut, &attr);
32  pthread_mutexattr_destroy(&attr);
33 }
34 #endif
35 
36 #ifdef HAVE_STRUCT_STAT_ST_ATIM
37 /* Linux */
38 #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec)
39 #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec)
40 #define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.tv_nsec)
41 #define ST_ATIM_NSEC_SET(stbuf, val) (stbuf)->st_atim.tv_nsec = (val)
42 #define ST_CTIM_NSEC_SET(stbuf, val) (stbuf)->st_ctim.tv_nsec = (val)
43 #define ST_MTIM_NSEC_SET(stbuf, val) (stbuf)->st_mtim.tv_nsec = (val)
44 #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC)
45 /* FreeBSD */
46 #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec)
47 #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec)
48 #define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.tv_nsec)
49 #define ST_ATIM_NSEC_SET(stbuf, val) (stbuf)->st_atimespec.tv_nsec = (val)
50 #define ST_CTIM_NSEC_SET(stbuf, val) (stbuf)->st_ctimespec.tv_nsec = (val)
51 #define ST_MTIM_NSEC_SET(stbuf, val) (stbuf)->st_mtimespec.tv_nsec = (val)
52 #else
53 #define ST_ATIM_NSEC(stbuf) 0
54 #define ST_CTIM_NSEC(stbuf) 0
55 #define ST_MTIM_NSEC(stbuf) 0
56 #define ST_ATIM_NSEC_SET(stbuf, val) do { } while (0)
57 #define ST_CTIM_NSEC_SET(stbuf, val) do { } while (0)
58 #define ST_MTIM_NSEC_SET(stbuf, val) do { } while (0)
59 #endif
+ + + + diff --git a/doc/html/fuse__opt_8c_source.html b/doc/html/fuse__opt_8c_source.html new file mode 100644 index 0000000..d37d90c --- /dev/null +++ b/doc/html/fuse__opt_8c_source.html @@ -0,0 +1,77 @@ + + + + + + + +libfuse: lib/fuse_opt.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_opt.c
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Implementation of option parsing routines (dealing with `struct
6  fuse_args`).
7 
8  This program can be distributed under the terms of the GNU LGPLv2.
9  See the file COPYING.LIB
10 */
11 
12 #include "config.h"
13 #include "fuse_opt.h"
14 #include "fuse_misc.h"
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <assert.h>
20 
21 struct fuse_opt_context {
22  void *data;
23  const struct fuse_opt *opt;
24  fuse_opt_proc_t proc;
25  int argctr;
26  int argc;
27  char **argv;
28  struct fuse_args outargs;
29  char *opts;
30  int nonopt;
31 };
32 
33 void fuse_opt_free_args(struct fuse_args *args)
34 {
35  if (args) {
36  if (args->argv && args->allocated) {
37  int i;
38  for (i = 0; i < args->argc; i++)
39  free(args->argv[i]);
40  free(args->argv);
41  }
42  args->argc = 0;
43  args->argv = NULL;
44  args->allocated = 0;
45  }
46 }
47 
48 static int alloc_failed(void)
49 {
50  fprintf(stderr, "fuse: memory allocation failed\n");
51  return -1;
52 }
53 
54 int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
55 {
56  char **newargv;
57  char *newarg;
58 
59  assert(!args->argv || args->allocated);
60 
61  newarg = strdup(arg);
62  if (!newarg)
63  return alloc_failed();
64 
65  newargv = realloc(args->argv, (args->argc + 2) * sizeof(char *));
66  if (!newargv) {
67  free(newarg);
68  return alloc_failed();
69  }
70 
71  args->argv = newargv;
72  args->allocated = 1;
73  args->argv[args->argc++] = newarg;
74  args->argv[args->argc] = NULL;
75  return 0;
76 }
77 
78 static int fuse_opt_insert_arg_common(struct fuse_args *args, int pos,
79  const char *arg)
80 {
81  assert(pos <= args->argc);
82  if (fuse_opt_add_arg(args, arg) == -1)
83  return -1;
84 
85  if (pos != args->argc - 1) {
86  char *newarg = args->argv[args->argc - 1];
87  memmove(&args->argv[pos + 1], &args->argv[pos],
88  sizeof(char *) * (args->argc - pos - 1));
89  args->argv[pos] = newarg;
90  }
91  return 0;
92 }
93 
94 int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg)
95 {
96  return fuse_opt_insert_arg_common(args, pos, arg);
97 }
98 
99 static int next_arg(struct fuse_opt_context *ctx, const char *opt)
100 {
101  if (ctx->argctr + 1 >= ctx->argc) {
102  fprintf(stderr, "fuse: missing argument after `%s'\n", opt);
103  return -1;
104  }
105  ctx->argctr++;
106  return 0;
107 }
108 
109 static int add_arg(struct fuse_opt_context *ctx, const char *arg)
110 {
111  return fuse_opt_add_arg(&ctx->outargs, arg);
112 }
113 
114 static int add_opt_common(char **opts, const char *opt, int esc)
115 {
116  unsigned oldlen = *opts ? strlen(*opts) : 0;
117  char *d = realloc(*opts, oldlen + 1 + strlen(opt) * 2 + 1);
118 
119  if (!d)
120  return alloc_failed();
121 
122  *opts = d;
123  if (oldlen) {
124  d += oldlen;
125  *d++ = ',';
126  }
127 
128  for (; *opt; opt++) {
129  if (esc && (*opt == ',' || *opt == '\\'))
130  *d++ = '\\';
131  *d++ = *opt;
132  }
133  *d = '\0';
134 
135  return 0;
136 }
137 
138 int fuse_opt_add_opt(char **opts, const char *opt)
139 {
140  return add_opt_common(opts, opt, 0);
141 }
142 
143 int fuse_opt_add_opt_escaped(char **opts, const char *opt)
144 {
145  return add_opt_common(opts, opt, 1);
146 }
147 
148 static int add_opt(struct fuse_opt_context *ctx, const char *opt)
149 {
150  return add_opt_common(&ctx->opts, opt, 1);
151 }
152 
153 static int call_proc(struct fuse_opt_context *ctx, const char *arg, int key,
154  int iso)
155 {
156  if (key == FUSE_OPT_KEY_DISCARD)
157  return 0;
158 
159  if (key != FUSE_OPT_KEY_KEEP && ctx->proc) {
160  int res = ctx->proc(ctx->data, arg, key, &ctx->outargs);
161  if (res == -1 || !res)
162  return res;
163  }
164  if (iso)
165  return add_opt(ctx, arg);
166  else
167  return add_arg(ctx, arg);
168 }
169 
170 static int match_template(const char *t, const char *arg, unsigned *sepp)
171 {
172  int arglen = strlen(arg);
173  const char *sep = strchr(t, '=');
174  sep = sep ? sep : strchr(t, ' ');
175  if (sep && (!sep[1] || sep[1] == '%')) {
176  int tlen = sep - t;
177  if (sep[0] == '=')
178  tlen ++;
179  if (arglen >= tlen && strncmp(arg, t, tlen) == 0) {
180  *sepp = sep - t;
181  return 1;
182  }
183  }
184  if (strcmp(t, arg) == 0) {
185  *sepp = 0;
186  return 1;
187  }
188  return 0;
189 }
190 
191 static const struct fuse_opt *find_opt(const struct fuse_opt *opt,
192  const char *arg, unsigned *sepp)
193 {
194  for (; opt && opt->templ; opt++)
195  if (match_template(opt->templ, arg, sepp))
196  return opt;
197  return NULL;
198 }
199 
200 int fuse_opt_match(const struct fuse_opt *opts, const char *opt)
201 {
202  unsigned dummy;
203  return find_opt(opts, opt, &dummy) ? 1 : 0;
204 }
205 
206 static int process_opt_param(void *var, const char *format, const char *param,
207  const char *arg)
208 {
209  assert(format[0] == '%');
210  if (format[1] == 's') {
211  char **s = var;
212  char *copy = strdup(param);
213  if (!copy)
214  return alloc_failed();
215 
216  free(*s);
217  *s = copy;
218  } else {
219  if (sscanf(param, format, var) != 1) {
220  fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg);
221  return -1;
222  }
223  }
224  return 0;
225 }
226 
227 static int process_opt(struct fuse_opt_context *ctx,
228  const struct fuse_opt *opt, unsigned sep,
229  const char *arg, int iso)
230 {
231  if (opt->offset == -1U) {
232  if (call_proc(ctx, arg, opt->value, iso) == -1)
233  return -1;
234  } else {
235  void *var = ctx->data + opt->offset;
236  if (sep && opt->templ[sep + 1]) {
237  const char *param = arg + sep;
238  if (opt->templ[sep] == '=')
239  param ++;
240  if (process_opt_param(var, opt->templ + sep + 1,
241  param, arg) == -1)
242  return -1;
243  } else
244  *(int *)var = opt->value;
245  }
246  return 0;
247 }
248 
249 static int process_opt_sep_arg(struct fuse_opt_context *ctx,
250  const struct fuse_opt *opt, unsigned sep,
251  const char *arg, int iso)
252 {
253  int res;
254  char *newarg;
255  char *param;
256 
257  if (next_arg(ctx, arg) == -1)
258  return -1;
259 
260  param = ctx->argv[ctx->argctr];
261  newarg = malloc(sep + strlen(param) + 1);
262  if (!newarg)
263  return alloc_failed();
264 
265  memcpy(newarg, arg, sep);
266  strcpy(newarg + sep, param);
267  res = process_opt(ctx, opt, sep, newarg, iso);
268  free(newarg);
269 
270  return res;
271 }
272 
273 static int process_gopt(struct fuse_opt_context *ctx, const char *arg, int iso)
274 {
275  unsigned sep;
276  const struct fuse_opt *opt = find_opt(ctx->opt, arg, &sep);
277  if (opt) {
278  for (; opt; opt = find_opt(opt + 1, arg, &sep)) {
279  int res;
280  if (sep && opt->templ[sep] == ' ' && !arg[sep])
281  res = process_opt_sep_arg(ctx, opt, sep, arg,
282  iso);
283  else
284  res = process_opt(ctx, opt, sep, arg, iso);
285  if (res == -1)
286  return -1;
287  }
288  return 0;
289  } else
290  return call_proc(ctx, arg, FUSE_OPT_KEY_OPT, iso);
291 }
292 
293 static int process_real_option_group(struct fuse_opt_context *ctx, char *opts)
294 {
295  char *s = opts;
296  char *d = s;
297  int end = 0;
298 
299  while (!end) {
300  if (*s == '\0')
301  end = 1;
302  if (*s == ',' || end) {
303  int res;
304 
305  *d = '\0';
306  res = process_gopt(ctx, opts, 1);
307  if (res == -1)
308  return -1;
309  d = opts;
310  } else {
311  if (s[0] == '\\' && s[1] != '\0') {
312  s++;
313  if (s[0] >= '0' && s[0] <= '3' &&
314  s[1] >= '0' && s[1] <= '7' &&
315  s[2] >= '0' && s[2] <= '7') {
316  *d++ = (s[0] - '0') * 0100 +
317  (s[1] - '0') * 0010 +
318  (s[2] - '0');
319  s += 2;
320  } else {
321  *d++ = *s;
322  }
323  } else {
324  *d++ = *s;
325  }
326  }
327  s++;
328  }
329 
330  return 0;
331 }
332 
333 static int process_option_group(struct fuse_opt_context *ctx, const char *opts)
334 {
335  int res;
336  char *copy = strdup(opts);
337 
338  if (!copy) {
339  fprintf(stderr, "fuse: memory allocation failed\n");
340  return -1;
341  }
342  res = process_real_option_group(ctx, copy);
343  free(copy);
344  return res;
345 }
346 
347 static int process_one(struct fuse_opt_context *ctx, const char *arg)
348 {
349  if (ctx->nonopt || arg[0] != '-')
350  return call_proc(ctx, arg, FUSE_OPT_KEY_NONOPT, 0);
351  else if (arg[1] == 'o') {
352  if (arg[2])
353  return process_option_group(ctx, arg + 2);
354  else {
355  if (next_arg(ctx, arg) == -1)
356  return -1;
357 
358  return process_option_group(ctx,
359  ctx->argv[ctx->argctr]);
360  }
361  } else if (arg[1] == '-' && !arg[2]) {
362  if (add_arg(ctx, arg) == -1)
363  return -1;
364  ctx->nonopt = ctx->outargs.argc;
365  return 0;
366  } else
367  return process_gopt(ctx, arg, 0);
368 }
369 
370 static int opt_parse(struct fuse_opt_context *ctx)
371 {
372  if (ctx->argc) {
373  if (add_arg(ctx, ctx->argv[0]) == -1)
374  return -1;
375  }
376 
377  for (ctx->argctr = 1; ctx->argctr < ctx->argc; ctx->argctr++)
378  if (process_one(ctx, ctx->argv[ctx->argctr]) == -1)
379  return -1;
380 
381  if (ctx->opts) {
382  if (fuse_opt_insert_arg(&ctx->outargs, 1, "-o") == -1 ||
383  fuse_opt_insert_arg(&ctx->outargs, 2, ctx->opts) == -1)
384  return -1;
385  }
386 
387  /* If option separator ("--") is the last argument, remove it */
388  if (ctx->nonopt && ctx->nonopt == ctx->outargs.argc &&
389  strcmp(ctx->outargs.argv[ctx->outargs.argc - 1], "--") == 0) {
390  free(ctx->outargs.argv[ctx->outargs.argc - 1]);
391  ctx->outargs.argv[--ctx->outargs.argc] = NULL;
392  }
393 
394  return 0;
395 }
396 
397 int fuse_opt_parse(struct fuse_args *args, void *data,
398  const struct fuse_opt opts[], fuse_opt_proc_t proc)
399 {
400  int res;
401  struct fuse_opt_context ctx = {
402  .data = data,
403  .opt = opts,
404  .proc = proc,
405  };
406 
407  if (!args || !args->argv || !args->argc)
408  return 0;
409 
410  ctx.argc = args->argc;
411  ctx.argv = args->argv;
412 
413  res = opt_parse(&ctx);
414  if (res != -1) {
415  struct fuse_args tmp = *args;
416  *args = ctx.outargs;
417  ctx.outargs = tmp;
418  }
419  free(ctx.opts);
420  fuse_opt_free_args(&ctx.outargs);
421  return res;
422 }
int fuse_opt_add_opt_escaped(char **opts, const char *opt)
Definition: fuse_opt.c:143
+
int argc
Definition: fuse_opt.h:111
+
unsigned long offset
Definition: fuse_opt.h:85
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
int allocated
Definition: fuse_opt.h:117
+
int value
Definition: fuse_opt.h:91
+
int fuse_opt_match(const struct fuse_opt opts[], const char *opt)
+
const char * templ
Definition: fuse_opt.h:79
+
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:54
+
#define FUSE_OPT_KEY_DISCARD
Definition: fuse_opt.h:153
+
#define FUSE_OPT_KEY_OPT
Definition: fuse_opt.h:129
+
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:33
+ +
#define FUSE_OPT_KEY_KEEP
Definition: fuse_opt.h:145
+
int fuse_opt_add_opt(char **opts, const char *opt)
Definition: fuse_opt.c:138
+
int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg)
Definition: fuse_opt.c:94
+
#define FUSE_OPT_KEY_NONOPT
Definition: fuse_opt.h:137
+
char ** argv
Definition: fuse_opt.h:114
+ + +
int(* fuse_opt_proc_t)(void *data, const char *arg, int key, struct fuse_args *outargs)
Definition: fuse_opt.h:180
+
+ + + + diff --git a/doc/html/fuse__opt_8h.html b/doc/html/fuse__opt_8h.html new file mode 100644 index 0000000..8d094be --- /dev/null +++ b/doc/html/fuse__opt_8h.html @@ -0,0 +1,588 @@ + + + + + + + +libfuse: include/fuse_opt.h File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+ +
+
fuse_opt.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + +

+Data Structures

struct  fuse_opt
 
struct  fuse_args
 
+ + + + + + + + + + + + + + + +

+Macros

#define FUSE_OPT_KEY(templ, key)   { templ, -1U, key }
 
#define FUSE_OPT_END   { NULL, 0, 0 }
 
#define FUSE_ARGS_INIT(argc, argv)   { argc, argv, 0 }
 
#define FUSE_OPT_KEY_OPT   -1
 
#define FUSE_OPT_KEY_NONOPT   -2
 
#define FUSE_OPT_KEY_KEEP   -3
 
#define FUSE_OPT_KEY_DISCARD   -4
 
+ + + +

+Typedefs

typedef int(* fuse_opt_proc_t) (void *data, const char *arg, int key, struct fuse_args *outargs)
 
+ + + + + + + + + + + + + + + +

+Functions

int fuse_opt_parse (struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
 
int fuse_opt_add_opt (char **opts, const char *opt)
 
int fuse_opt_add_opt_escaped (char **opts, const char *opt)
 
int fuse_opt_add_arg (struct fuse_args *args, const char *arg)
 
int fuse_opt_insert_arg (struct fuse_args *args, int pos, const char *arg)
 
void fuse_opt_free_args (struct fuse_args *args)
 
int fuse_opt_match (const struct fuse_opt opts[], const char *opt)
 
+

Detailed Description

+

This file defines the option parsing interface of FUSE

+ +

Definition in file fuse_opt.h.

+

Macro Definition Documentation

+ +

◆ FUSE_ARGS_INIT

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define FUSE_ARGS_INIT( argc,
 argv 
)   { argc, argv, 0 }
+
+

Initializer for 'struct fuse_args'

+ +

Definition at line 123 of file fuse_opt.h.

+ +
+
+ +

◆ FUSE_OPT_END

+ +
+
+ + + + +
#define FUSE_OPT_END   { NULL, 0, 0 }
+
+

Last option. An array of 'struct fuse_opt' must end with a NULL template value

+ +

Definition at line 104 of file fuse_opt.h.

+ +
+
+ +

◆ FUSE_OPT_KEY

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define FUSE_OPT_KEY( templ,
 key 
)   { templ, -1U, key }
+
+

Key option. In case of a match, the processing function will be called with the specified key.

+ +

Definition at line 98 of file fuse_opt.h.

+ +
+
+ +

◆ FUSE_OPT_KEY_DISCARD

+ +
+
+ + + + +
#define FUSE_OPT_KEY_DISCARD   -4
+
+

Special key value for options to discard

+

Argument is not passed to processing function, but behave as if the processing function returned zero

+ +

Definition at line 153 of file fuse_opt.h.

+ +
+
+ +

◆ FUSE_OPT_KEY_KEEP

+ +
+
+ + + + +
#define FUSE_OPT_KEY_KEEP   -3
+
+

Special key value for options to keep

+

Argument is not passed to processing function, but behave as if the processing function returned 1

+ +

Definition at line 145 of file fuse_opt.h.

+ +
+
+ +

◆ FUSE_OPT_KEY_NONOPT

+ +
+
+ + + + +
#define FUSE_OPT_KEY_NONOPT   -2
+
+

Key value passed to the processing function for all non-options

+

Non-options are the arguments beginning with a character other than '-' or all arguments after the special '–' option

+ +

Definition at line 137 of file fuse_opt.h.

+ +
+
+ +

◆ FUSE_OPT_KEY_OPT

+ +
+
+ + + + +
#define FUSE_OPT_KEY_OPT   -1
+
+

Key value passed to the processing function if an option did not match any template

+ +

Definition at line 129 of file fuse_opt.h.

+ +
+
+

Typedef Documentation

+ +

◆ fuse_opt_proc_t

+ +
+
+ + + + +
typedef int(* fuse_opt_proc_t) (void *data, const char *arg, int key, struct fuse_args *outargs)
+
+

Processing function

+

This function is called if

    +
  • option did not match any 'struct fuse_opt'
  • +
  • argument is a non-option
  • +
  • option did match and offset was set to -1
  • +
+

The 'arg' parameter will always contain the whole argument or option including the parameter if exists. A two-argument option ("-x foo") is always converted to single argument option of the form "-xfoo" before this function is called.

+

Options of the form '-ofoo' are passed to this function without the '-o' prefix.

+

The return value of this function determines whether this argument is to be inserted into the output argument vector, or discarded.

+
Parameters
+ + + + + +
datais the user data passed to the fuse_opt_parse() function
argis the whole argument or option
keydetermines why the processing function was called
outargsthe current output argument list
+
+
+
Returns
-1 on error, 0 if arg is to be discarded, 1 if arg should be kept
+ +

Definition at line 180 of file fuse_opt.h.

+ +
+
+

Function Documentation

+ +

◆ fuse_opt_add_arg()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_opt_add_arg (struct fuse_argsargs,
const char * arg 
)
+
+

Add an argument to a NULL terminated argument vector

+
Parameters
+ + + +
argsis the structure containing the current argument list
argis the new argument to add
+
+
+
Returns
-1 on allocation error, 0 on success
+ +

Definition at line 54 of file fuse_opt.c.

+ +
+
+ +

◆ fuse_opt_add_opt()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_opt_add_opt (char ** opts,
const char * opt 
)
+
+

Add an option to a comma separated option list

+
Parameters
+ + + +
optsis a pointer to an option list, may point to a NULL value
optis the option to add
+
+
+
Returns
-1 on allocation error, 0 on success
+ +

Definition at line 138 of file fuse_opt.c.

+ +
+
+ +

◆ fuse_opt_add_opt_escaped()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_opt_add_opt_escaped (char ** opts,
const char * opt 
)
+
+

Add an option, escaping commas, to a comma separated option list

+
Parameters
+ + + +
optsis a pointer to an option list, may point to a NULL value
optis the option to add
+
+
+
Returns
-1 on allocation error, 0 on success
+ +

Definition at line 143 of file fuse_opt.c.

+ +
+
+ +

◆ fuse_opt_free_args()

+ +
+
+ + + + + + + + +
void fuse_opt_free_args (struct fuse_argsargs)
+
+

Free the contents of argument list

+

The structure itself is not freed

+
Parameters
+ + +
argsis the structure containing the argument list
+
+
+ +

Definition at line 33 of file fuse_opt.c.

+ +
+
+ +

◆ fuse_opt_insert_arg()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_opt_insert_arg (struct fuse_argsargs,
int pos,
const char * arg 
)
+
+

Add an argument at the specified position in a NULL terminated argument vector

+

Adds the argument to the N-th position. This is useful for adding options at the beginning of the array which must not come after the special '–' option.

+
Parameters
+ + + + +
argsis the structure containing the current argument list
posis the position at which to add the argument
argis the new argument to add
+
+
+
Returns
-1 on allocation error, 0 on success
+ +

Definition at line 94 of file fuse_opt.c.

+ +
+
+ +

◆ fuse_opt_match()

+ +
+
+ + + + + + + + + + + + + + + + + + +
int fuse_opt_match (const struct fuse_opt opts[],
const char * opt 
)
+
+

Check if an option matches

+
Parameters
+ + + +
optsis the option description array
optis the option to match
+
+
+
Returns
1 if a match is found, 0 if not
+ +
+
+ +

◆ fuse_opt_parse()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int fuse_opt_parse (struct fuse_argsargs,
void * data,
const struct fuse_opt opts[],
fuse_opt_proc_t proc 
)
+
+

Option parsing function

+

If 'args' was returned from a previous call to fuse_opt_parse() or it was constructed from

+

A NULL 'args' is equivalent to an empty argument vector

+

A NULL 'opts' is equivalent to an 'opts' array containing a single end marker

+

A NULL 'proc' is equivalent to a processing function always returning '1'

+
Parameters
+ + + + + +
argsis the input and output argument list
datais the user data
optsis the option description array
procis the processing function
+
+
+
Returns
-1 on error, 0 on success
+ +

Definition at line 397 of file fuse_opt.c.

+ +
+
+
+ + + + diff --git a/doc/html/fuse__opt_8h_source.html b/doc/html/fuse__opt_8h_source.html new file mode 100644 index 0000000..d937052 --- /dev/null +++ b/doc/html/fuse__opt_8h_source.html @@ -0,0 +1,72 @@ + + + + + + + +libfuse: include/fuse_opt.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_opt.h
+
+
+Go to the documentation of this file.
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU LGPLv2.
6  See the file COPYING.LIB.
7 */
8 
9 #ifndef FUSE_OPT_H_
10 #define FUSE_OPT_H_
11 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
77 struct fuse_opt {
79  const char *templ;
80 
85  unsigned long offset;
86 
91  int value;
92 };
93 
98 #define FUSE_OPT_KEY(templ, key) { templ, -1U, key }
99 
104 #define FUSE_OPT_END { NULL, 0, 0 }
105 
109 struct fuse_args {
111  int argc;
112 
114  char **argv;
115 
118 };
119 
123 #define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 }
124 
129 #define FUSE_OPT_KEY_OPT -1
130 
137 #define FUSE_OPT_KEY_NONOPT -2
138 
145 #define FUSE_OPT_KEY_KEEP -3
146 
153 #define FUSE_OPT_KEY_DISCARD -4
154 
180 typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key,
181  struct fuse_args *outargs);
182 
203 int fuse_opt_parse(struct fuse_args *args, void *data,
204  const struct fuse_opt opts[], fuse_opt_proc_t proc);
205 
213 int fuse_opt_add_opt(char **opts, const char *opt);
214 
222 int fuse_opt_add_opt_escaped(char **opts, const char *opt);
223 
231 int fuse_opt_add_arg(struct fuse_args *args, const char *arg);
232 
246 int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg);
247 
255 void fuse_opt_free_args(struct fuse_args *args);
256 
257 
265 int fuse_opt_match(const struct fuse_opt opts[], const char *opt);
266 
267 #ifdef __cplusplus
268 }
269 #endif
270 
271 #endif /* FUSE_OPT_H_ */
int fuse_opt_add_opt_escaped(char **opts, const char *opt)
Definition: fuse_opt.c:143
+
int argc
Definition: fuse_opt.h:111
+
unsigned long offset
Definition: fuse_opt.h:85
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
int allocated
Definition: fuse_opt.h:117
+
int value
Definition: fuse_opt.h:91
+
int fuse_opt_match(const struct fuse_opt opts[], const char *opt)
+
const char * templ
Definition: fuse_opt.h:79
+
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:54
+
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:33
+
int fuse_opt_add_opt(char **opts, const char *opt)
Definition: fuse_opt.c:138
+
int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg)
Definition: fuse_opt.c:94
+
char ** argv
Definition: fuse_opt.h:114
+ + +
int(* fuse_opt_proc_t)(void *data, const char *arg, int key, struct fuse_args *outargs)
Definition: fuse_opt.h:180
+
+ + + + diff --git a/doc/html/fuse__signals_8c_source.html b/doc/html/fuse__signals_8c_source.html new file mode 100644 index 0000000..68cfb14 --- /dev/null +++ b/doc/html/fuse__signals_8c_source.html @@ -0,0 +1,60 @@ + + + + + + + +libfuse: lib/fuse_signals.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fuse_signals.c
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Utility functions for setting signal handlers.
6 
7  This program can be distributed under the terms of the GNU LGPLv2.
8  See the file COPYING.LIB
9 */
10 
11 #include "config.h"
12 #include "fuse_lowlevel.h"
13 #include "fuse_i.h"
14 
15 #include <stdio.h>
16 #include <string.h>
17 #include <signal.h>
18 #include <stdlib.h>
19 
20 static struct fuse_session *fuse_instance;
21 
22 static void exit_handler(int sig)
23 {
24  if (fuse_instance) {
25  fuse_session_exit(fuse_instance);
26  if(sig <= 0) {
27  fprintf(stderr, "assertion error: signal value <= 0\n");
28  abort();
29  }
30  fuse_instance->error = sig;
31  }
32 }
33 
34 static void do_nothing(int sig)
35 {
36  (void) sig;
37 }
38 
39 static int set_one_signal_handler(int sig, void (*handler)(int), int remove)
40 {
41  struct sigaction sa;
42  struct sigaction old_sa;
43 
44  memset(&sa, 0, sizeof(struct sigaction));
45  sa.sa_handler = remove ? SIG_DFL : handler;
46  sigemptyset(&(sa.sa_mask));
47  sa.sa_flags = 0;
48 
49  if (sigaction(sig, NULL, &old_sa) == -1) {
50  perror("fuse: cannot get old signal handler");
51  return -1;
52  }
53 
54  if (old_sa.sa_handler == (remove ? handler : SIG_DFL) &&
55  sigaction(sig, &sa, NULL) == -1) {
56  perror("fuse: cannot set signal handler");
57  return -1;
58  }
59  return 0;
60 }
61 
62 int fuse_set_signal_handlers(struct fuse_session *se)
63 {
64  /* If we used SIG_IGN instead of the do_nothing function,
65  then we would be unable to tell if we set SIG_IGN (and
66  thus should reset to SIG_DFL in fuse_remove_signal_handlers)
67  or if it was already set to SIG_IGN (and should be left
68  untouched. */
69  if (set_one_signal_handler(SIGHUP, exit_handler, 0) == -1 ||
70  set_one_signal_handler(SIGINT, exit_handler, 0) == -1 ||
71  set_one_signal_handler(SIGTERM, exit_handler, 0) == -1 ||
72  set_one_signal_handler(SIGPIPE, do_nothing, 0) == -1)
73  return -1;
74 
75  fuse_instance = se;
76  return 0;
77 }
78 
79 void fuse_remove_signal_handlers(struct fuse_session *se)
80 {
81  if (fuse_instance != se)
82  fprintf(stderr,
83  "fuse: fuse_remove_signal_handlers: unknown session\n");
84  else
85  fuse_instance = NULL;
86 
87  set_one_signal_handler(SIGHUP, exit_handler, 1);
88  set_one_signal_handler(SIGINT, exit_handler, 1);
89  set_one_signal_handler(SIGTERM, exit_handler, 1);
90  set_one_signal_handler(SIGPIPE, do_nothing, 1);
91 }
void fuse_session_exit(struct fuse_session *se)
+
int fuse_set_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:62
+
void fuse_remove_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:79
+ +
+ + + + diff --git a/doc/html/fusermount_8c_source.html b/doc/html/fusermount_8c_source.html new file mode 100644 index 0000000..9ac34d5 --- /dev/null +++ b/doc/html/fusermount_8c_source.html @@ -0,0 +1,56 @@ + + + + + + + +libfuse: util/fusermount.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
fusermount.c
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU GPL.
6  See the file COPYING.
7 */
8 /* This program does the mounting and unmounting of FUSE filesystems */
9 
10 #define _GNU_SOURCE /* for clone */
11 #include <config.h>
12 
13 #include "mount_util.h"
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include <unistd.h>
19 #include <getopt.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <pwd.h>
23 #include <paths.h>
24 #include <mntent.h>
25 #include <sys/wait.h>
26 #include <sys/stat.h>
27 #include <sys/mount.h>
28 #include <sys/fsuid.h>
29 #include <sys/socket.h>
30 #include <sys/utsname.h>
31 #include <sched.h>
32 #include <stdbool.h>
33 #include <sys/vfs.h>
34 
35 #define FUSE_COMMFD_ENV "_FUSE_COMMFD"
36 
37 #define FUSE_DEV "/dev/fuse"
38 
39 #ifndef MS_DIRSYNC
40 #define MS_DIRSYNC 128
41 #endif
42 #ifndef MS_REC
43 #define MS_REC 16384
44 #endif
45 #ifndef MS_PRIVATE
46 #define MS_PRIVATE (1<<18)
47 #endif
48 
49 #ifndef UMOUNT_DETACH
50 #define UMOUNT_DETACH 0x00000002 /* Just detach from the tree */
51 #endif
52 #ifndef UMOUNT_NOFOLLOW
53 #define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */
54 #endif
55 #ifndef UMOUNT_UNUSED
56 #define UMOUNT_UNUSED 0x80000000 /* Flag guaranteed to be unused */
57 #endif
58 
59 static const char *progname;
60 
61 static int user_allow_other = 0;
62 static int mount_max = 1000;
63 
64 static int auto_unmount = 0;
65 
66 static const char *get_user_name(void)
67 {
68  struct passwd *pw = getpwuid(getuid());
69  if (pw != NULL && pw->pw_name != NULL)
70  return pw->pw_name;
71  else {
72  fprintf(stderr, "%s: could not determine username\n", progname);
73  return NULL;
74  }
75 }
76 
77 static uid_t oldfsuid;
78 static gid_t oldfsgid;
79 
80 static void drop_privs(void)
81 {
82  if (getuid() != 0) {
83  oldfsuid = setfsuid(getuid());
84  oldfsgid = setfsgid(getgid());
85  }
86 }
87 
88 static void restore_privs(void)
89 {
90  if (getuid() != 0) {
91  setfsuid(oldfsuid);
92  setfsgid(oldfsgid);
93  }
94 }
95 
96 #ifndef IGNORE_MTAB
97 /*
98  * Make sure that /etc/mtab is checked and updated atomically
99  */
100 static int lock_umount(void)
101 {
102  const char *mtab_lock = _PATH_MOUNTED ".fuselock";
103  int mtablock;
104  int res;
105  struct stat mtab_stat;
106 
107  /* /etc/mtab could be a symlink to /proc/mounts */
108  if (lstat(_PATH_MOUNTED, &mtab_stat) == 0 && S_ISLNK(mtab_stat.st_mode))
109  return -1;
110 
111  mtablock = open(mtab_lock, O_RDWR | O_CREAT, 0600);
112  if (mtablock == -1) {
113  fprintf(stderr, "%s: unable to open fuse lock file: %s\n",
114  progname, strerror(errno));
115  return -1;
116  }
117  res = lockf(mtablock, F_LOCK, 0);
118  if (res < 0) {
119  fprintf(stderr, "%s: error getting lock: %s\n", progname,
120  strerror(errno));
121  close(mtablock);
122  return -1;
123  }
124 
125  return mtablock;
126 }
127 
128 static void unlock_umount(int mtablock)
129 {
130  if (mtablock >= 0) {
131  int res;
132 
133  res = lockf(mtablock, F_ULOCK, 0);
134  if (res < 0) {
135  fprintf(stderr, "%s: error releasing lock: %s\n",
136  progname, strerror(errno));
137  }
138  close(mtablock);
139  }
140 }
141 
142 static int add_mount(const char *source, const char *mnt, const char *type,
143  const char *opts)
144 {
145  return fuse_mnt_add_mount(progname, source, mnt, type, opts);
146 }
147 
148 static int may_unmount(const char *mnt, int quiet)
149 {
150  struct mntent *entp;
151  FILE *fp;
152  const char *user = NULL;
153  char uidstr[32];
154  unsigned uidlen = 0;
155  int found;
156  const char *mtab = _PATH_MOUNTED;
157 
158  user = get_user_name();
159  if (user == NULL)
160  return -1;
161 
162  fp = setmntent(mtab, "r");
163  if (fp == NULL) {
164  fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
165  strerror(errno));
166  return -1;
167  }
168 
169  uidlen = sprintf(uidstr, "%u", getuid());
170 
171  found = 0;
172  while ((entp = getmntent(fp)) != NULL) {
173  if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
174  (strcmp(entp->mnt_type, "fuse") == 0 ||
175  strcmp(entp->mnt_type, "fuseblk") == 0 ||
176  strncmp(entp->mnt_type, "fuse.", 5) == 0 ||
177  strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) {
178  char *p = strstr(entp->mnt_opts, "user=");
179  if (p &&
180  (p == entp->mnt_opts || *(p-1) == ',') &&
181  strcmp(p + 5, user) == 0) {
182  found = 1;
183  break;
184  }
185  /* /etc/mtab is a link pointing to
186  /proc/mounts: */
187  else if ((p =
188  strstr(entp->mnt_opts, "user_id=")) &&
189  (p == entp->mnt_opts ||
190  *(p-1) == ',') &&
191  strncmp(p + 8, uidstr, uidlen) == 0 &&
192  (*(p+8+uidlen) == ',' ||
193  *(p+8+uidlen) == '\0')) {
194  found = 1;
195  break;
196  }
197  }
198  }
199  endmntent(fp);
200 
201  if (!found) {
202  if (!quiet)
203  fprintf(stderr,
204  "%s: entry for %s not found in %s\n",
205  progname, mnt, mtab);
206  return -1;
207  }
208 
209  return 0;
210 }
211 
212 /*
213  * Check whether the file specified in "fusermount3 -u" is really a
214  * mountpoint and not a symlink. This is necessary otherwise the user
215  * could move the mountpoint away and replace it with a symlink
216  * pointing to an arbitrary mount, thereby tricking fusermount3 into
217  * unmounting that (umount(2) will follow symlinks).
218  *
219  * This is the child process running in a separate mount namespace, so
220  * we don't mess with the global namespace and if the process is
221  * killed for any reason, mounts are automatically cleaned up.
222  *
223  * First make sure nothing is propagated back into the parent
224  * namespace by marking all mounts "private".
225  *
226  * Then bind mount parent onto a stable base where the user can't move
227  * it around.
228  *
229  * Finally check /proc/mounts for an entry matching the requested
230  * mountpoint. If it's found then we are OK, and the user can't move
231  * it around within the parent directory as rename() will return
232  * EBUSY. Be careful to ignore any mounts that existed before the
233  * bind.
234  */
235 static int check_is_mount_child(void *p)
236 {
237  const char **a = p;
238  const char *last = a[0];
239  const char *mnt = a[1];
240  const char *type = a[2];
241  int res;
242  const char *procmounts = "/proc/mounts";
243  int found;
244  FILE *fp;
245  struct mntent *entp;
246  int count;
247 
248  res = mount("", "/", "", MS_PRIVATE | MS_REC, NULL);
249  if (res == -1) {
250  fprintf(stderr, "%s: failed to mark mounts private: %s\n",
251  progname, strerror(errno));
252  return 1;
253  }
254 
255  fp = setmntent(procmounts, "r");
256  if (fp == NULL) {
257  fprintf(stderr, "%s: failed to open %s: %s\n", progname,
258  procmounts, strerror(errno));
259  return 1;
260  }
261 
262  count = 0;
263  while (getmntent(fp) != NULL)
264  count++;
265  endmntent(fp);
266 
267  fp = setmntent(procmounts, "r");
268  if (fp == NULL) {
269  fprintf(stderr, "%s: failed to open %s: %s\n", progname,
270  procmounts, strerror(errno));
271  return 1;
272  }
273 
274  res = mount(".", "/", "", MS_BIND | MS_REC, NULL);
275  if (res == -1) {
276  fprintf(stderr, "%s: failed to bind parent to /: %s\n",
277  progname, strerror(errno));
278  return 1;
279  }
280 
281  found = 0;
282  while ((entp = getmntent(fp)) != NULL) {
283  if (count > 0) {
284  count--;
285  continue;
286  }
287  if (entp->mnt_dir[0] == '/' &&
288  strcmp(entp->mnt_dir + 1, last) == 0 &&
289  (!type || strcmp(entp->mnt_type, type) == 0)) {
290  found = 1;
291  break;
292  }
293  }
294  endmntent(fp);
295 
296  if (!found) {
297  fprintf(stderr, "%s: %s not mounted\n", progname, mnt);
298  return 1;
299  }
300 
301  return 0;
302 }
303 
304 static pid_t clone_newns(void *a)
305 {
306  char buf[131072];
307  char *stack = buf + (sizeof(buf) / 2 - ((size_t) buf & 15));
308 
309 #ifdef __ia64__
310  extern int __clone2(int (*fn)(void *),
311  void *child_stack_base, size_t stack_size,
312  int flags, void *arg, pid_t *ptid,
313  void *tls, pid_t *ctid);
314 
315  return __clone2(check_is_mount_child, stack, sizeof(buf) / 2,
316  CLONE_NEWNS, a, NULL, NULL, NULL);
317 #else
318  return clone(check_is_mount_child, stack, CLONE_NEWNS, a);
319 #endif
320 }
321 
322 static int check_is_mount(const char *last, const char *mnt, const char *type)
323 {
324  pid_t pid, p;
325  int status;
326  const char *a[3] = { last, mnt, type };
327 
328  pid = clone_newns((void *) a);
329  if (pid == (pid_t) -1) {
330  fprintf(stderr, "%s: failed to clone namespace: %s\n",
331  progname, strerror(errno));
332  return -1;
333  }
334  p = waitpid(pid, &status, __WCLONE);
335  if (p == (pid_t) -1) {
336  fprintf(stderr, "%s: waitpid failed: %s\n",
337  progname, strerror(errno));
338  return -1;
339  }
340  if (!WIFEXITED(status)) {
341  fprintf(stderr, "%s: child terminated abnormally (status %i)\n",
342  progname, status);
343  return -1;
344  }
345  if (WEXITSTATUS(status) != 0)
346  return -1;
347 
348  return 0;
349 }
350 
351 static int chdir_to_parent(char *copy, const char **lastp)
352 {
353  char *tmp;
354  const char *parent;
355  char buf[65536];
356  int res;
357 
358  tmp = strrchr(copy, '/');
359  if (tmp == NULL || tmp[1] == '\0') {
360  fprintf(stderr, "%s: internal error: invalid abs path: <%s>\n",
361  progname, copy);
362  return -1;
363  }
364  if (tmp != copy) {
365  *tmp = '\0';
366  parent = copy;
367  *lastp = tmp + 1;
368  } else if (tmp[1] != '\0') {
369  *lastp = tmp + 1;
370  parent = "/";
371  } else {
372  *lastp = ".";
373  parent = "/";
374  }
375 
376  res = chdir(parent);
377  if (res == -1) {
378  fprintf(stderr, "%s: failed to chdir to %s: %s\n",
379  progname, parent, strerror(errno));
380  return -1;
381  }
382 
383  if (getcwd(buf, sizeof(buf)) == NULL) {
384  fprintf(stderr, "%s: failed to obtain current directory: %s\n",
385  progname, strerror(errno));
386  return -1;
387  }
388  if (strcmp(buf, parent) != 0) {
389  fprintf(stderr, "%s: mountpoint moved (%s -> %s)\n", progname,
390  parent, buf);
391  return -1;
392 
393  }
394 
395  return 0;
396 }
397 
398 /* Check whether the kernel supports UMOUNT_NOFOLLOW flag */
399 static int umount_nofollow_support(void)
400 {
401  int res = umount2("", UMOUNT_UNUSED);
402  if (res != -1 || errno != EINVAL)
403  return 0;
404 
405  res = umount2("", UMOUNT_NOFOLLOW);
406  if (res != -1 || errno != ENOENT)
407  return 0;
408 
409  return 1;
410 }
411 
412 static int unmount_fuse_locked(const char *mnt, int quiet, int lazy)
413 {
414  int res;
415  char *copy;
416  const char *last;
417  int umount_flags = lazy ? UMOUNT_DETACH : 0;
418 
419  if (getuid() != 0) {
420  res = may_unmount(mnt, quiet);
421  if (res == -1)
422  return -1;
423  }
424 
425  copy = strdup(mnt);
426  if (copy == NULL) {
427  fprintf(stderr, "%s: failed to allocate memory\n", progname);
428  return -1;
429  }
430 
431  res = chdir_to_parent(copy, &last);
432  if (res == -1)
433  goto out;
434 
435  if (umount_nofollow_support()) {
436  umount_flags |= UMOUNT_NOFOLLOW;
437  } else {
438  res = check_is_mount(last, mnt, NULL);
439  if (res == -1)
440  goto out;
441  }
442 
443  res = umount2(last, umount_flags);
444  if (res == -1 && !quiet) {
445  fprintf(stderr, "%s: failed to unmount %s: %s\n",
446  progname, mnt, strerror(errno));
447  }
448 
449 out:
450  free(copy);
451  if (res == -1)
452  return -1;
453 
454  res = chdir("/");
455  if (res == -1) {
456  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
457  return -1;
458  }
459 
460  return fuse_mnt_remove_mount(progname, mnt);
461 }
462 
463 static int unmount_fuse(const char *mnt, int quiet, int lazy)
464 {
465  int res;
466  int mtablock = lock_umount();
467 
468  res = unmount_fuse_locked(mnt, quiet, lazy);
469  unlock_umount(mtablock);
470 
471  return res;
472 }
473 
474 static int count_fuse_fs(void)
475 {
476  struct mntent *entp;
477  int count = 0;
478  const char *mtab = _PATH_MOUNTED;
479  FILE *fp = setmntent(mtab, "r");
480  if (fp == NULL) {
481  fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
482  strerror(errno));
483  return -1;
484  }
485  while ((entp = getmntent(fp)) != NULL) {
486  if (strcmp(entp->mnt_type, "fuse") == 0 ||
487  strncmp(entp->mnt_type, "fuse.", 5) == 0)
488  count ++;
489  }
490  endmntent(fp);
491  return count;
492 }
493 
494 
495 #else /* IGNORE_MTAB */
496 static int count_fuse_fs(void)
497 {
498  return 0;
499 }
500 
501 static int add_mount(const char *source, const char *mnt, const char *type,
502  const char *opts)
503 {
504  (void) source;
505  (void) mnt;
506  (void) type;
507  (void) opts;
508  return 0;
509 }
510 
511 static int unmount_fuse(const char *mnt, int quiet, int lazy)
512 {
513  (void) quiet;
514  return fuse_mnt_umount(progname, mnt, mnt, lazy);
515 }
516 #endif /* IGNORE_MTAB */
517 
518 static void strip_line(char *line)
519 {
520  char *s = strchr(line, '#');
521  if (s != NULL)
522  s[0] = '\0';
523  for (s = line + strlen(line) - 1;
524  s >= line && isspace((unsigned char) *s); s--);
525  s[1] = '\0';
526  for (s = line; isspace((unsigned char) *s); s++);
527  if (s != line)
528  memmove(line, s, strlen(s)+1);
529 }
530 
531 static void parse_line(char *line, int linenum)
532 {
533  int tmp;
534  if (strcmp(line, "user_allow_other") == 0)
535  user_allow_other = 1;
536  else if (sscanf(line, "mount_max = %i", &tmp) == 1)
537  mount_max = tmp;
538  else if(line[0])
539  fprintf(stderr,
540  "%s: unknown parameter in %s at line %i: '%s'\n",
541  progname, FUSE_CONF, linenum, line);
542 }
543 
544 static void read_conf(void)
545 {
546  FILE *fp = fopen(FUSE_CONF, "r");
547  if (fp != NULL) {
548  int linenum = 1;
549  char line[256];
550  int isnewline = 1;
551  while (fgets(line, sizeof(line), fp) != NULL) {
552  if (isnewline) {
553  if (line[strlen(line)-1] == '\n') {
554  strip_line(line);
555  parse_line(line, linenum);
556  } else {
557  isnewline = 0;
558  }
559  } else if(line[strlen(line)-1] == '\n') {
560  fprintf(stderr, "%s: reading %s: line %i too long\n", progname, FUSE_CONF, linenum);
561 
562  isnewline = 1;
563  }
564  if (isnewline)
565  linenum ++;
566  }
567  if (!isnewline) {
568  fprintf(stderr, "%s: reading %s: missing newline at end of file\n", progname, FUSE_CONF);
569 
570  }
571  if (ferror(fp)) {
572  fprintf(stderr, "%s: reading %s: read failed\n", progname, FUSE_CONF);
573  exit(1);
574  }
575  fclose(fp);
576  } else if (errno != ENOENT) {
577  bool fatal = (errno != EACCES && errno != ELOOP &&
578  errno != ENAMETOOLONG && errno != ENOTDIR &&
579  errno != EOVERFLOW);
580  fprintf(stderr, "%s: failed to open %s: %s\n",
581  progname, FUSE_CONF, strerror(errno));
582  if (fatal)
583  exit(1);
584  }
585 }
586 
587 static int begins_with(const char *s, const char *beg)
588 {
589  if (strncmp(s, beg, strlen(beg)) == 0)
590  return 1;
591  else
592  return 0;
593 }
594 
595 struct mount_flags {
596  const char *opt;
597  unsigned long flag;
598  int on;
599  int safe;
600 };
601 
602 static struct mount_flags mount_flags[] = {
603  {"rw", MS_RDONLY, 0, 1},
604  {"ro", MS_RDONLY, 1, 1},
605  {"suid", MS_NOSUID, 0, 0},
606  {"nosuid", MS_NOSUID, 1, 1},
607  {"dev", MS_NODEV, 0, 0},
608  {"nodev", MS_NODEV, 1, 1},
609  {"exec", MS_NOEXEC, 0, 1},
610  {"noexec", MS_NOEXEC, 1, 1},
611  {"async", MS_SYNCHRONOUS, 0, 1},
612  {"sync", MS_SYNCHRONOUS, 1, 1},
613  {"atime", MS_NOATIME, 0, 1},
614  {"noatime", MS_NOATIME, 1, 1},
615  {"dirsync", MS_DIRSYNC, 1, 1},
616  {NULL, 0, 0, 0}
617 };
618 
619 static int find_mount_flag(const char *s, unsigned len, int *on, int *flag)
620 {
621  int i;
622 
623  for (i = 0; mount_flags[i].opt != NULL; i++) {
624  const char *opt = mount_flags[i].opt;
625  if (strlen(opt) == len && strncmp(opt, s, len) == 0) {
626  *on = mount_flags[i].on;
627  *flag = mount_flags[i].flag;
628  if (!mount_flags[i].safe && getuid() != 0) {
629  *flag = 0;
630  fprintf(stderr,
631  "%s: unsafe option %s ignored\n",
632  progname, opt);
633  }
634  return 1;
635  }
636  }
637  return 0;
638 }
639 
640 static int add_option(char **optsp, const char *opt, unsigned expand)
641 {
642  char *newopts;
643  if (*optsp == NULL)
644  newopts = strdup(opt);
645  else {
646  unsigned oldsize = strlen(*optsp);
647  unsigned newsize = oldsize + 1 + strlen(opt) + expand + 1;
648  newopts = (char *) realloc(*optsp, newsize);
649  if (newopts)
650  sprintf(newopts + oldsize, ",%s", opt);
651  }
652  if (newopts == NULL) {
653  fprintf(stderr, "%s: failed to allocate memory\n", progname);
654  return -1;
655  }
656  *optsp = newopts;
657  return 0;
658 }
659 
660 static int get_mnt_opts(int flags, char *opts, char **mnt_optsp)
661 {
662  int i;
663  int l;
664 
665  if (!(flags & MS_RDONLY) && add_option(mnt_optsp, "rw", 0) == -1)
666  return -1;
667 
668  for (i = 0; mount_flags[i].opt != NULL; i++) {
669  if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
670  add_option(mnt_optsp, mount_flags[i].opt, 0) == -1)
671  return -1;
672  }
673 
674  if (add_option(mnt_optsp, opts, 0) == -1)
675  return -1;
676  /* remove comma from end of opts*/
677  l = strlen(*mnt_optsp);
678  if ((*mnt_optsp)[l-1] == ',')
679  (*mnt_optsp)[l-1] = '\0';
680  if (getuid() != 0) {
681  const char *user = get_user_name();
682  if (user == NULL)
683  return -1;
684 
685  if (add_option(mnt_optsp, "user=", strlen(user)) == -1)
686  return -1;
687  strcat(*mnt_optsp, user);
688  }
689  return 0;
690 }
691 
692 static int opt_eq(const char *s, unsigned len, const char *opt)
693 {
694  if(strlen(opt) == len && strncmp(s, opt, len) == 0)
695  return 1;
696  else
697  return 0;
698 }
699 
700 static int get_string_opt(const char *s, unsigned len, const char *opt,
701  char **val)
702 {
703  int i;
704  unsigned opt_len = strlen(opt);
705  char *d;
706 
707  if (*val)
708  free(*val);
709  *val = (char *) malloc(len - opt_len + 1);
710  if (!*val) {
711  fprintf(stderr, "%s: failed to allocate memory\n", progname);
712  return 0;
713  }
714 
715  d = *val;
716  s += opt_len;
717  len -= opt_len;
718  for (i = 0; i < len; i++) {
719  if (s[i] == '\\' && i + 1 < len)
720  i++;
721  *d++ = s[i];
722  }
723  *d = '\0';
724  return 1;
725 }
726 
727 /* The kernel silently truncates the "data" argument to PAGE_SIZE-1 characters.
728  * This can be dangerous if it e.g. truncates the option "group_id=1000" to
729  * "group_id=1".
730  * This wrapper detects this case and bails out with an error.
731  */
732 static int mount_notrunc(const char *source, const char *target,
733  const char *filesystemtype, unsigned long mountflags,
734  const char *data) {
735  if (strlen(data) > sysconf(_SC_PAGESIZE) - 1) {
736  fprintf(stderr, "%s: mount options too long\n", progname);
737  errno = EINVAL;
738  return -1;
739  }
740  return mount(source, target, filesystemtype, mountflags, data);
741 }
742 
743 
744 static int do_mount(const char *mnt, const char **typep, mode_t rootmode,
745  int fd, const char *opts, const char *dev, char **sourcep,
746  char **mnt_optsp)
747 {
748  int res;
749  int flags = MS_NOSUID | MS_NODEV;
750  char *optbuf;
751  char *mnt_opts = NULL;
752  const char *s;
753  char *d;
754  char *fsname = NULL;
755  char *subtype = NULL;
756  char *source = NULL;
757  char *type = NULL;
758  int blkdev = 0;
759 
760  optbuf = (char *) malloc(strlen(opts) + 128);
761  if (!optbuf) {
762  fprintf(stderr, "%s: failed to allocate memory\n", progname);
763  return -1;
764  }
765 
766  for (s = opts, d = optbuf; *s;) {
767  unsigned len;
768  const char *fsname_str = "fsname=";
769  const char *subtype_str = "subtype=";
770  bool escape_ok = begins_with(s, fsname_str) ||
771  begins_with(s, subtype_str);
772  for (len = 0; s[len]; len++) {
773  if (escape_ok && s[len] == '\\' && s[len + 1])
774  len++;
775  else if (s[len] == ',')
776  break;
777  }
778  if (begins_with(s, fsname_str)) {
779  if (!get_string_opt(s, len, fsname_str, &fsname))
780  goto err;
781  } else if (begins_with(s, subtype_str)) {
782  if (!get_string_opt(s, len, subtype_str, &subtype))
783  goto err;
784  } else if (opt_eq(s, len, "blkdev")) {
785  if (getuid() != 0) {
786  fprintf(stderr,
787  "%s: option blkdev is privileged\n",
788  progname);
789  goto err;
790  }
791  blkdev = 1;
792  } else if (opt_eq(s, len, "auto_unmount")) {
793  auto_unmount = 1;
794  } else if (!begins_with(s, "fd=") &&
795  !begins_with(s, "rootmode=") &&
796  !begins_with(s, "user_id=") &&
797  !begins_with(s, "group_id=")) {
798  int on;
799  int flag;
800  int skip_option = 0;
801  if (opt_eq(s, len, "large_read")) {
802  struct utsname utsname;
803  unsigned kmaj, kmin;
804  res = uname(&utsname);
805  if (res == 0 &&
806  sscanf(utsname.release, "%u.%u",
807  &kmaj, &kmin) == 2 &&
808  (kmaj > 2 || (kmaj == 2 && kmin > 4))) {
809  fprintf(stderr, "%s: note: 'large_read' mount option is deprecated for %i.%i kernels\n", progname, kmaj, kmin);
810  skip_option = 1;
811  }
812  }
813  if (getuid() != 0 && !user_allow_other &&
814  (opt_eq(s, len, "allow_other") ||
815  opt_eq(s, len, "allow_root"))) {
816  fprintf(stderr, "%s: option %.*s only allowed if 'user_allow_other' is set in %s\n", progname, len, s, FUSE_CONF);
817  goto err;
818  }
819  if (!skip_option) {
820  if (find_mount_flag(s, len, &on, &flag)) {
821  if (on)
822  flags |= flag;
823  else
824  flags &= ~flag;
825  } else if (opt_eq(s, len, "default_permissions") ||
826  opt_eq(s, len, "allow_other") ||
827  begins_with(s, "max_read=") ||
828  begins_with(s, "blksize=")) {
829  memcpy(d, s, len);
830  d += len;
831  *d++ = ',';
832  } else {
833  fprintf(stderr, "%s: unknown option '%.*s'\n", progname, len, s);
834  exit(1);
835  }
836  }
837  }
838  s += len;
839  if (*s)
840  s++;
841  }
842  *d = '\0';
843  res = get_mnt_opts(flags, optbuf, &mnt_opts);
844  if (res == -1)
845  goto err;
846 
847  sprintf(d, "fd=%i,rootmode=%o,user_id=%u,group_id=%u",
848  fd, rootmode, getuid(), getgid());
849 
850  source = malloc((fsname ? strlen(fsname) : 0) +
851  (subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
852 
853  type = malloc((subtype ? strlen(subtype) : 0) + 32);
854  if (!type || !source) {
855  fprintf(stderr, "%s: failed to allocate memory\n", progname);
856  goto err;
857  }
858 
859  if (subtype)
860  sprintf(type, "%s.%s", blkdev ? "fuseblk" : "fuse", subtype);
861  else
862  strcpy(type, blkdev ? "fuseblk" : "fuse");
863 
864  if (fsname)
865  strcpy(source, fsname);
866  else
867  strcpy(source, subtype ? subtype : dev);
868 
869  res = mount_notrunc(source, mnt, type, flags, optbuf);
870  if (res == -1 && errno == ENODEV && subtype) {
871  /* Probably missing subtype support */
872  strcpy(type, blkdev ? "fuseblk" : "fuse");
873  if (fsname) {
874  if (!blkdev)
875  sprintf(source, "%s#%s", subtype, fsname);
876  } else {
877  strcpy(source, type);
878  }
879 
880  res = mount_notrunc(source, mnt, type, flags, optbuf);
881  }
882  if (res == -1 && errno == EINVAL) {
883  /* It could be an old version not supporting group_id */
884  sprintf(d, "fd=%i,rootmode=%o,user_id=%u",
885  fd, rootmode, getuid());
886  res = mount_notrunc(source, mnt, type, flags, optbuf);
887  }
888  if (res == -1) {
889  int errno_save = errno;
890  if (blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
891  fprintf(stderr, "%s: 'fuseblk' support missing\n",
892  progname);
893  else
894  fprintf(stderr, "%s: mount failed: %s\n", progname,
895  strerror(errno_save));
896  goto err;
897  }
898  *sourcep = source;
899  *typep = type;
900  *mnt_optsp = mnt_opts;
901  free(fsname);
902  free(optbuf);
903 
904  return 0;
905 
906 err:
907  free(fsname);
908  free(subtype);
909  free(source);
910  free(type);
911  free(mnt_opts);
912  free(optbuf);
913  return -1;
914 }
915 
916 static int check_perm(const char **mntp, struct stat *stbuf, int *mountpoint_fd)
917 {
918  int res;
919  const char *mnt = *mntp;
920  const char *origmnt = mnt;
921  struct statfs fs_buf;
922  size_t i;
923 
924  res = lstat(mnt, stbuf);
925  if (res == -1) {
926  fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
927  progname, mnt, strerror(errno));
928  return -1;
929  }
930 
931  /* No permission checking is done for root */
932  if (getuid() == 0)
933  return 0;
934 
935  if (S_ISDIR(stbuf->st_mode)) {
936  res = chdir(mnt);
937  if (res == -1) {
938  fprintf(stderr,
939  "%s: failed to chdir to mountpoint: %s\n",
940  progname, strerror(errno));
941  return -1;
942  }
943  mnt = *mntp = ".";
944  res = lstat(mnt, stbuf);
945  if (res == -1) {
946  fprintf(stderr,
947  "%s: failed to access mountpoint %s: %s\n",
948  progname, origmnt, strerror(errno));
949  return -1;
950  }
951 
952  if ((stbuf->st_mode & S_ISVTX) && stbuf->st_uid != getuid()) {
953  fprintf(stderr, "%s: mountpoint %s not owned by user\n",
954  progname, origmnt);
955  return -1;
956  }
957 
958  res = access(mnt, W_OK);
959  if (res == -1) {
960  fprintf(stderr, "%s: user has no write access to mountpoint %s\n",
961  progname, origmnt);
962  return -1;
963  }
964  } else if (S_ISREG(stbuf->st_mode)) {
965  static char procfile[256];
966  *mountpoint_fd = open(mnt, O_WRONLY);
967  if (*mountpoint_fd == -1) {
968  fprintf(stderr, "%s: failed to open %s: %s\n",
969  progname, mnt, strerror(errno));
970  return -1;
971  }
972  res = fstat(*mountpoint_fd, stbuf);
973  if (res == -1) {
974  fprintf(stderr,
975  "%s: failed to access mountpoint %s: %s\n",
976  progname, mnt, strerror(errno));
977  return -1;
978  }
979  if (!S_ISREG(stbuf->st_mode)) {
980  fprintf(stderr,
981  "%s: mountpoint %s is no longer a regular file\n",
982  progname, mnt);
983  return -1;
984  }
985 
986  sprintf(procfile, "/proc/self/fd/%i", *mountpoint_fd);
987  *mntp = procfile;
988  } else {
989  fprintf(stderr,
990  "%s: mountpoint %s is not a directory or a regular file\n",
991  progname, mnt);
992  return -1;
993  }
994 
995  /* Do not permit mounting over anything in procfs - it has a couple
996  * places to which we have "write access" without being supposed to be
997  * able to just put anything we want there.
998  * Luckily, without allow_other, we can't get other users to actually
999  * use any fake information we try to put there anyway.
1000  * Use a whitelist to be safe. */
1001  if (statfs(*mntp, &fs_buf)) {
1002  fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
1003  progname, mnt, strerror(errno));
1004  return -1;
1005  }
1006 
1007  /* Define permitted filesystems for the mount target. This was
1008  * originally the same list as used by the ecryptfs mount helper
1009  * (https://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/view/head:/src/utils/mount.ecryptfs_private.c#L225)
1010  * but got expanded as we found more filesystems that needed to be
1011  * overlayed. */
1012  typeof(fs_buf.f_type) f_type_whitelist[] = {
1013  0x61756673 /* AUFS_SUPER_MAGIC */,
1014  0x00000187 /* AUTOFS_SUPER_MAGIC */,
1015  0xCA451A4E /* BCACHEFS_STATFS_MAGIC */,
1016  0x9123683E /* BTRFS_SUPER_MAGIC */,
1017  0x00C36400 /* CEPH_SUPER_MAGIC */,
1018  0xFF534D42 /* CIFS_MAGIC_NUMBER */,
1019  0X00004D44 /* MSDOS_SUPER_MAGIC */,
1020  0x0000F15F /* ECRYPTFS_SUPER_MAGIC */,
1021  0x0000EF53 /* EXT[234]_SUPER_MAGIC */,
1022  0xF2F52010 /* F2FS_SUPER_MAGIC */,
1023  0x65735546 /* FUSE_SUPER_MAGIC */,
1024  0x01161970 /* GFS2_MAGIC */,
1025  0x47504653 /* GPFS_SUPER_MAGIC */,
1026  0x3153464A /* JFS_SUPER_MAGIC */,
1027  0x000072B6 /* JFFS2_SUPER_MAGIC */,
1028  0x0BD00BD0 /* LL_SUPER_MAGIC */,
1029  0x0000564C /* NCP_SUPER_MAGIC */,
1030  0x00006969 /* NFS_SUPER_MAGIC */,
1031  0x00003434 /* NILFS_SUPER_MAGIC */,
1032  0x5346544E /* NTFS_SB_MAGIC */,
1033  0x794C7630 /* OVERLAYFS_SUPER_MAGIC */,
1034  0x52654973 /* REISERFS_SUPER_MAGIC */,
1035  0x73717368 /* SQUASHFS_MAGIC */,
1036  0x01021994 /* TMPFS_MAGIC */,
1037  0x24051905 /* UBIFS_SUPER_MAGIC */,
1038  0x58465342 /* XFS_SB_MAGIC */,
1039  0x2FC12FC1 /* ZFS_SUPER_MAGIC */,
1040  };
1041  for (i = 0; i < sizeof(f_type_whitelist)/sizeof(f_type_whitelist[0]); i++) {
1042  if (f_type_whitelist[i] == fs_buf.f_type)
1043  return 0;
1044  }
1045 
1046  fprintf(stderr, "%s: mounting over filesystem type %#010lx is forbidden\n",
1047  progname, (unsigned long)fs_buf.f_type);
1048  return -1;
1049 }
1050 
1051 static int try_open(const char *dev, char **devp, int silent)
1052 {
1053  int fd = open(dev, O_RDWR);
1054  if (fd != -1) {
1055  *devp = strdup(dev);
1056  if (*devp == NULL) {
1057  fprintf(stderr, "%s: failed to allocate memory\n",
1058  progname);
1059  close(fd);
1060  fd = -1;
1061  }
1062  } else if (errno == ENODEV ||
1063  errno == ENOENT)/* check for ENOENT too, for the udev case */
1064  return -2;
1065  else if (!silent) {
1066  fprintf(stderr, "%s: failed to open %s: %s\n", progname, dev,
1067  strerror(errno));
1068  }
1069  return fd;
1070 }
1071 
1072 static int try_open_fuse_device(char **devp)
1073 {
1074  int fd;
1075 
1076  drop_privs();
1077  fd = try_open(FUSE_DEV, devp, 0);
1078  restore_privs();
1079  return fd;
1080 }
1081 
1082 static int open_fuse_device(char **devp)
1083 {
1084  int fd = try_open_fuse_device(devp);
1085  if (fd >= -1)
1086  return fd;
1087 
1088  fprintf(stderr,
1089  "%s: fuse device not found, try 'modprobe fuse' first\n",
1090  progname);
1091 
1092  return -1;
1093 }
1094 
1095 
1096 static int mount_fuse(const char *mnt, const char *opts, const char **type)
1097 {
1098  int res;
1099  int fd;
1100  char *dev;
1101  struct stat stbuf;
1102  char *source = NULL;
1103  char *mnt_opts = NULL;
1104  const char *real_mnt = mnt;
1105  int mountpoint_fd = -1;
1106 
1107  fd = open_fuse_device(&dev);
1108  if (fd == -1)
1109  return -1;
1110 
1111  drop_privs();
1112  read_conf();
1113 
1114  if (getuid() != 0 && mount_max != -1) {
1115  int mount_count = count_fuse_fs();
1116  if (mount_count >= mount_max) {
1117  fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in %s\n", progname, FUSE_CONF);
1118  goto fail_close_fd;
1119  }
1120  }
1121 
1122  res = check_perm(&real_mnt, &stbuf, &mountpoint_fd);
1123  restore_privs();
1124  if (res != -1)
1125  res = do_mount(real_mnt, type, stbuf.st_mode & S_IFMT,
1126  fd, opts, dev, &source, &mnt_opts);
1127 
1128  if (mountpoint_fd != -1)
1129  close(mountpoint_fd);
1130 
1131  if (res == -1)
1132  goto fail_close_fd;
1133 
1134  res = chdir("/");
1135  if (res == -1) {
1136  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1137  goto fail_close_fd;
1138  }
1139 
1140  if (geteuid() == 0) {
1141  res = add_mount(source, mnt, *type, mnt_opts);
1142  if (res == -1) {
1143  /* Can't clean up mount in a non-racy way */
1144  goto fail_close_fd;
1145  }
1146  }
1147 
1148 out_free:
1149  free(source);
1150  free(mnt_opts);
1151  free(dev);
1152 
1153  return fd;
1154 
1155 fail_close_fd:
1156  close(fd);
1157  fd = -1;
1158  goto out_free;
1159 }
1160 
1161 static int send_fd(int sock_fd, int fd)
1162 {
1163  int retval;
1164  struct msghdr msg;
1165  struct cmsghdr *p_cmsg;
1166  struct iovec vec;
1167  size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)];
1168  int *p_fds;
1169  char sendchar = 0;
1170 
1171  msg.msg_control = cmsgbuf;
1172  msg.msg_controllen = sizeof(cmsgbuf);
1173  p_cmsg = CMSG_FIRSTHDR(&msg);
1174  p_cmsg->cmsg_level = SOL_SOCKET;
1175  p_cmsg->cmsg_type = SCM_RIGHTS;
1176  p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
1177  p_fds = (int *) CMSG_DATA(p_cmsg);
1178  *p_fds = fd;
1179  msg.msg_controllen = p_cmsg->cmsg_len;
1180  msg.msg_name = NULL;
1181  msg.msg_namelen = 0;
1182  msg.msg_iov = &vec;
1183  msg.msg_iovlen = 1;
1184  msg.msg_flags = 0;
1185  /* "To pass file descriptors or credentials you need to send/read at
1186  * least one byte" (man 7 unix) */
1187  vec.iov_base = &sendchar;
1188  vec.iov_len = sizeof(sendchar);
1189  while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
1190  if (retval != 1) {
1191  perror("sending file descriptor");
1192  return -1;
1193  }
1194  return 0;
1195 }
1196 
1197 /* The parent fuse process has died: decide whether to auto_unmount.
1198  *
1199  * In the normal case (umount or fusermount -u), the filesystem
1200  * has already been unmounted. If we simply unmount again we can
1201  * cause problems with stacked mounts (e.g. autofs).
1202  *
1203  * So we unmount here only in abnormal case where fuse process has
1204  * died without unmount happening. To detect this, we first look in
1205  * the mount table to make sure the mountpoint is still mounted and
1206  * has proper type. If so, we then see if opening the mount dir is
1207  * returning 'Transport endpoint is not connected'.
1208  *
1209  * The order of these is important, because if autofs is in use,
1210  * opening the dir to check for ENOTCONN will cause a new mount
1211  * in the normal case where filesystem has been unmounted cleanly.
1212  */
1213 static int should_auto_unmount(const char *mnt, const char *type)
1214 {
1215  char *copy;
1216  const char *last;
1217  int result = 0;
1218  int fd;
1219 
1220  copy = strdup(mnt);
1221  if (copy == NULL) {
1222  fprintf(stderr, "%s: failed to allocate memory\n", progname);
1223  return 0;
1224  }
1225 
1226  if (chdir_to_parent(copy, &last) == -1)
1227  goto out;
1228  if (check_is_mount(last, mnt, type) == -1)
1229  goto out;
1230 
1231  fd = open(mnt, O_RDONLY);
1232  if (fd != -1) {
1233  close(fd);
1234  } else {
1235  result = errno == ENOTCONN;
1236  }
1237 out:
1238  free(copy);
1239  return result;
1240 }
1241 
1242 static void usage(void)
1243 {
1244  printf("%s: [options] mountpoint\n"
1245  "Options:\n"
1246  " -h print help\n"
1247  " -V print version\n"
1248  " -o opt[,opt...] mount options\n"
1249  " -u unmount\n"
1250  " -q quiet\n"
1251  " -z lazy unmount\n",
1252  progname);
1253  exit(1);
1254 }
1255 
1256 static void show_version(void)
1257 {
1258  printf("fusermount3 version: %s\n", PACKAGE_VERSION);
1259  exit(0);
1260 }
1261 
1262 int main(int argc, char *argv[])
1263 {
1264  sigset_t sigset;
1265  int ch;
1266  int fd;
1267  int res;
1268  char *origmnt;
1269  char *mnt;
1270  static int unmount = 0;
1271  static int lazy = 0;
1272  static int quiet = 0;
1273  char *commfd;
1274  int cfd;
1275  const char *opts = "";
1276  const char *type = NULL;
1277 
1278  static const struct option long_opts[] = {
1279  {"unmount", no_argument, NULL, 'u'},
1280  {"lazy", no_argument, NULL, 'z'},
1281  {"quiet", no_argument, NULL, 'q'},
1282  {"help", no_argument, NULL, 'h'},
1283  {"version", no_argument, NULL, 'V'},
1284  {0, 0, 0, 0}};
1285 
1286  progname = strdup(argv[0]);
1287  if (progname == NULL) {
1288  fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
1289  exit(1);
1290  }
1291 
1292  while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts,
1293  NULL)) != -1) {
1294  switch (ch) {
1295  case 'h':
1296  usage();
1297  break;
1298 
1299  case 'V':
1300  show_version();
1301  break;
1302 
1303  case 'o':
1304  opts = optarg;
1305  break;
1306 
1307  case 'u':
1308  unmount = 1;
1309  break;
1310 
1311  case 'z':
1312  lazy = 1;
1313  break;
1314 
1315  case 'q':
1316  quiet = 1;
1317  break;
1318 
1319  default:
1320  exit(1);
1321  }
1322  }
1323 
1324  if (lazy && !unmount) {
1325  fprintf(stderr, "%s: -z can only be used with -u\n", progname);
1326  exit(1);
1327  }
1328 
1329  if (optind >= argc) {
1330  fprintf(stderr, "%s: missing mountpoint argument\n", progname);
1331  exit(1);
1332  } else if (argc > optind + 1) {
1333  fprintf(stderr, "%s: extra arguments after the mountpoint\n",
1334  progname);
1335  exit(1);
1336  }
1337 
1338  origmnt = argv[optind];
1339 
1340  drop_privs();
1341  mnt = fuse_mnt_resolve_path(progname, origmnt);
1342  if (mnt != NULL) {
1343  res = chdir("/");
1344  if (res == -1) {
1345  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1346  goto err_out;
1347  }
1348  }
1349  restore_privs();
1350  if (mnt == NULL)
1351  exit(1);
1352 
1353  umask(033);
1354  if (unmount)
1355  goto do_unmount;
1356 
1357  commfd = getenv(FUSE_COMMFD_ENV);
1358  if (commfd == NULL) {
1359  fprintf(stderr, "%s: old style mounting not supported\n",
1360  progname);
1361  goto err_out;
1362  }
1363 
1364  fd = mount_fuse(mnt, opts, &type);
1365  if (fd == -1)
1366  goto err_out;
1367 
1368  cfd = atoi(commfd);
1369  res = send_fd(cfd, fd);
1370  if (res == -1)
1371  goto err_out;
1372  close(fd);
1373 
1374  if (!auto_unmount) {
1375  free(mnt);
1376  return 0;
1377  }
1378 
1379  /* Become a daemon and wait for the parent to exit or die.
1380  ie For the control socket to get closed.
1381  btw We don't want to use daemon() function here because
1382  it forks and messes with the file descriptors. */
1383  setsid();
1384  res = chdir("/");
1385  if (res == -1) {
1386  fprintf(stderr, "%s: failed to chdir to '/'\n", progname);
1387  goto err_out;
1388  }
1389 
1390  sigfillset(&sigset);
1391  sigprocmask(SIG_BLOCK, &sigset, NULL);
1392 
1393  lazy = 1;
1394  quiet = 1;
1395 
1396  while (1) {
1397  unsigned char buf[16];
1398  int n = recv(cfd, buf, sizeof(buf), 0);
1399  if (!n)
1400  break;
1401 
1402  if (n < 0) {
1403  if (errno == EINTR)
1404  continue;
1405  break;
1406  }
1407  }
1408 
1409  if (!should_auto_unmount(mnt, type)) {
1410  goto success_out;
1411  }
1412 
1413 do_unmount:
1414  if (geteuid() == 0)
1415  res = unmount_fuse(mnt, quiet, lazy);
1416  else {
1417  res = umount2(mnt, lazy ? UMOUNT_DETACH : 0);
1418  if (res == -1 && !quiet)
1419  fprintf(stderr,
1420  "%s: failed to unmount %s: %s\n",
1421  progname, mnt, strerror(errno));
1422  }
1423  if (res == -1)
1424  goto err_out;
1425 
1426 success_out:
1427  free(mnt);
1428  return 0;
1429 
1430 err_out:
1431  free(mnt);
1432  exit(1);
1433 }
+ + + + diff --git a/doc/html/globals.html b/doc/html/globals.html new file mode 100644 index 0000000..e1aba7f --- /dev/null +++ b/doc/html/globals.html @@ -0,0 +1,457 @@ + + + + + + + +libfuse: Globals + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- f -

+
+ + + + diff --git a/doc/html/globals_defs.html b/doc/html/globals_defs.html new file mode 100644 index 0000000..d545bb8 --- /dev/null +++ b/doc/html/globals_defs.html @@ -0,0 +1,148 @@ + + + + + + + +libfuse: Globals + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+  + +

- f -

+
+ + + + diff --git a/doc/html/globals_enum.html b/doc/html/globals_enum.html new file mode 100644 index 0000000..db74df8 --- /dev/null +++ b/doc/html/globals_enum.html @@ -0,0 +1,62 @@ + + + + + + + +libfuse: Globals + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+
+ + + + diff --git a/doc/html/globals_eval.html b/doc/html/globals_eval.html new file mode 100644 index 0000000..0ad5f27 --- /dev/null +++ b/doc/html/globals_eval.html @@ -0,0 +1,77 @@ + + + + + + + +libfuse: Globals + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+
+ + + + diff --git a/doc/html/globals_func.html b/doc/html/globals_func.html new file mode 100644 index 0000000..75621b2 --- /dev/null +++ b/doc/html/globals_func.html @@ -0,0 +1,304 @@ + + + + + + + +libfuse: Globals + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+  + +

- f -

+
+ + + + diff --git a/doc/html/globals_type.html b/doc/html/globals_type.html new file mode 100644 index 0000000..181e6db --- /dev/null +++ b/doc/html/globals_type.html @@ -0,0 +1,68 @@ + + + + + + + +libfuse: Globals + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+
+ + + + diff --git a/doc/html/hello_8c.html b/doc/html/hello_8c.html new file mode 100644 index 0000000..487d44c --- /dev/null +++ b/doc/html/hello_8c.html @@ -0,0 +1,71 @@ + + + + + + + +libfuse: example/hello.c File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
hello.c File Reference
+
+
+
#include <fuse.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <assert.h>
+
+

Go to the source code of this file.

+

Detailed Description

+

minimal example filesystem using high-level API

+

Compile with:

gcc -Wall hello.c `pkg-config fuse3 --cflags --libs` -o hello
+

Source code

+
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
*/
#define FUSE_USE_VERSION 31
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <assert.h>
/*
* Command line options
*
* We can't set default values for the char* fields here because
* fuse_opt_parse would attempt to free() them when the user specifies
* different values on the command line.
*/
static struct options {
const char *filename;
const char *contents;
int show_help;
} options;
#define OPTION(t, p) \
{ t, offsetof(struct options, p), 1 }
static const struct fuse_opt option_spec[] = {
OPTION("--name=%s", filename),
OPTION("--contents=%s", contents),
OPTION("-h", show_help),
OPTION("--help", show_help),
};
static void *hello_init(struct fuse_conn_info *conn,
struct fuse_config *cfg)
{
(void) conn;
cfg->kernel_cache = 1;
return NULL;
}
static int hello_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi)
{
(void) fi;
int res = 0;
memset(stbuf, 0, sizeof(struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path+1, options.filename) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(options.contents);
} else
res = -ENOENT;
return res;
}
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags)
{
(void) offset;
(void) fi;
(void) flags;
if (strcmp(path, "/") != 0)
return -ENOENT;
filler(buf, ".", NULL, 0, 0);
filler(buf, "..", NULL, 0, 0);
filler(buf, options.filename, NULL, 0, 0);
return 0;
}
static int hello_open(const char *path, struct fuse_file_info *fi)
{
if (strcmp(path+1, options.filename) != 0)
return -ENOENT;
if ((fi->flags & O_ACCMODE) != O_RDONLY)
return -EACCES;
return 0;
}
static int hello_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
size_t len;
(void) fi;
if(strcmp(path+1, options.filename) != 0)
return -ENOENT;
len = strlen(options.contents);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, options.contents + offset, size);
} else
size = 0;
return size;
}
static struct fuse_operations hello_oper = {
.init = hello_init,
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
static void show_help(const char *progname)
{
printf("usage: %s [options] <mountpoint>\n\n", progname);
printf("File-system specific options:\n"
" --name=<s> Name of the \"hello\" file\n"
" (default: \"hello\")\n"
" --contents=<s> Contents \"hello\" file\n"
" (default \"Hello, World!\\n\")\n"
"\n");
}
int main(int argc, char *argv[])
{
int ret;
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
/* Set defaults -- we have to use strdup so that
fuse_opt_parse can free the defaults if other
values are specified */
options.filename = strdup("hello");
options.contents = strdup("Hello World!\n");
/* Parse options */
if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1)
return 1;
/* When --help is specified, first print our own file-system
specific help text, then signal fuse_main to show
additional help (by adding `--help` to the options again)
without usage: line (by setting argv[0] to the empty
string) */
if (options.show_help) {
show_help(argv[0]);
assert(fuse_opt_add_arg(&args, "--help") == 0);
args.argv[0][0] = '\0';
}
ret = fuse_main(args.argc, args.argv, &hello_oper, NULL);
return ret;
}
+

Definition in file hello.c.

+
+ + + + diff --git a/doc/html/hello_8c_source.html b/doc/html/hello_8c_source.html new file mode 100644 index 0000000..bc82343 --- /dev/null +++ b/doc/html/hello_8c_source.html @@ -0,0 +1,77 @@ + + + + + + + +libfuse: example/hello.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
hello.c
+
+
+Go to the documentation of this file.
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU GPL.
6  See the file COPYING.
7 */
8 
22 #define FUSE_USE_VERSION 31
23 
24 #include <fuse.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <stddef.h>
30 #include <assert.h>
31 
32 /*
33  * Command line options
34  *
35  * We can't set default values for the char* fields here because
36  * fuse_opt_parse would attempt to free() them when the user specifies
37  * different values on the command line.
38  */
39 static struct options {
40  const char *filename;
41  const char *contents;
42  int show_help;
43 } options;
44 
45 #define OPTION(t, p) \
46  { t, offsetof(struct options, p), 1 }
47 static const struct fuse_opt option_spec[] = {
48  OPTION("--name=%s", filename),
49  OPTION("--contents=%s", contents),
50  OPTION("-h", show_help),
51  OPTION("--help", show_help),
53 };
54 
55 static void *hello_init(struct fuse_conn_info *conn,
56  struct fuse_config *cfg)
57 {
58  (void) conn;
59  cfg->kernel_cache = 1;
60  return NULL;
61 }
62 
63 static int hello_getattr(const char *path, struct stat *stbuf,
64  struct fuse_file_info *fi)
65 {
66  (void) fi;
67  int res = 0;
68 
69  memset(stbuf, 0, sizeof(struct stat));
70  if (strcmp(path, "/") == 0) {
71  stbuf->st_mode = S_IFDIR | 0755;
72  stbuf->st_nlink = 2;
73  } else if (strcmp(path+1, options.filename) == 0) {
74  stbuf->st_mode = S_IFREG | 0444;
75  stbuf->st_nlink = 1;
76  stbuf->st_size = strlen(options.contents);
77  } else
78  res = -ENOENT;
79 
80  return res;
81 }
82 
83 static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
84  off_t offset, struct fuse_file_info *fi,
85  enum fuse_readdir_flags flags)
86 {
87  (void) offset;
88  (void) fi;
89  (void) flags;
90 
91  if (strcmp(path, "/") != 0)
92  return -ENOENT;
93 
94  filler(buf, ".", NULL, 0, 0);
95  filler(buf, "..", NULL, 0, 0);
96  filler(buf, options.filename, NULL, 0, 0);
97 
98  return 0;
99 }
100 
101 static int hello_open(const char *path, struct fuse_file_info *fi)
102 {
103  if (strcmp(path+1, options.filename) != 0)
104  return -ENOENT;
105 
106  if ((fi->flags & O_ACCMODE) != O_RDONLY)
107  return -EACCES;
108 
109  return 0;
110 }
111 
112 static int hello_read(const char *path, char *buf, size_t size, off_t offset,
113  struct fuse_file_info *fi)
114 {
115  size_t len;
116  (void) fi;
117  if(strcmp(path+1, options.filename) != 0)
118  return -ENOENT;
119 
120  len = strlen(options.contents);
121  if (offset < len) {
122  if (offset + size > len)
123  size = len - offset;
124  memcpy(buf, options.contents + offset, size);
125  } else
126  size = 0;
127 
128  return size;
129 }
130 
131 static struct fuse_operations hello_oper = {
132  .init = hello_init,
133  .getattr = hello_getattr,
134  .readdir = hello_readdir,
135  .open = hello_open,
136  .read = hello_read,
137 };
138 
139 static void show_help(const char *progname)
140 {
141  printf("usage: %s [options] <mountpoint>\n\n", progname);
142  printf("File-system specific options:\n"
143  " --name=<s> Name of the \"hello\" file\n"
144  " (default: \"hello\")\n"
145  " --contents=<s> Contents \"hello\" file\n"
146  " (default \"Hello, World!\\n\")\n"
147  "\n");
148 }
149 
150 int main(int argc, char *argv[])
151 {
152  int ret;
153  struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
154 
155  /* Set defaults -- we have to use strdup so that
156  fuse_opt_parse can free the defaults if other
157  values are specified */
158  options.filename = strdup("hello");
159  options.contents = strdup("Hello World!\n");
160 
161  /* Parse options */
162  if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1)
163  return 1;
164 
165  /* When --help is specified, first print our own file-system
166  specific help text, then signal fuse_main to show
167  additional help (by adding `--help` to the options again)
168  without usage: line (by setting argv[0] to the empty
169  string) */
170  if (options.show_help) {
171  show_help(argv[0]);
172  assert(fuse_opt_add_arg(&args, "--help") == 0);
173  args.argv[0][0] = '\0';
174  }
175 
176  ret = fuse_main(args.argc, args.argv, &hello_oper, NULL);
177  fuse_opt_free_args(&args);
178  return ret;
179 }
+
int argc
Definition: fuse_opt.h:111
+
unsigned long offset
Definition: fuse_opt.h:85
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
fuse_readdir_flags
Definition: fuse.h:42
+
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:54
+ +
void *(* init)(struct fuse_conn_info *conn, struct fuse_config *cfg)
Definition: fuse.h:572
+ + +
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:33
+
#define FUSE_OPT_END
Definition: fuse_opt.h:104
+ +
char ** argv
Definition: fuse_opt.h:114
+
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:82
+ + + +
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
+
int kernel_cache
Definition: fuse.h:237
+
#define fuse_main(argc, argv, op, private_data)
Definition: fuse.h:855
+
+ + + + diff --git a/doc/html/hello__ll_8c.html b/doc/html/hello__ll_8c.html new file mode 100644 index 0000000..56bde00 --- /dev/null +++ b/doc/html/hello__ll_8c.html @@ -0,0 +1,72 @@ + + + + + + + +libfuse: example/hello_ll.c File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
hello_ll.c File Reference
+
+
+
#include <fuse_lowlevel.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+
+

Go to the source code of this file.

+

Detailed Description

+

minimal example filesystem using low-level API

+

Compile with:

gcc -Wall hello_ll.c `pkg-config fuse3 --cflags --libs` -o hello_ll
+

Source code

+
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
*/
#define FUSE_USE_VERSION 31
#include <fuse_lowlevel.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
static const char *hello_str = "Hello World!\n";
static const char *hello_name = "hello";
static int hello_stat(fuse_ino_t ino, struct stat *stbuf)
{
stbuf->st_ino = ino;
switch (ino) {
case 1:
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
break;
case 2:
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(hello_str);
break;
default:
return -1;
}
return 0;
}
static void hello_ll_getattr(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
struct stat stbuf;
(void) fi;
memset(&stbuf, 0, sizeof(stbuf));
if (hello_stat(ino, &stbuf) == -1)
fuse_reply_err(req, ENOENT);
else
fuse_reply_attr(req, &stbuf, 1.0);
}
static void hello_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
{
struct fuse_entry_param e;
if (parent != 1 || strcmp(name, hello_name) != 0)
fuse_reply_err(req, ENOENT);
else {
memset(&e, 0, sizeof(e));
e.ino = 2;
e.attr_timeout = 1.0;
e.entry_timeout = 1.0;
hello_stat(e.ino, &e.attr);
fuse_reply_entry(req, &e);
}
}
struct dirbuf {
char *p;
size_t size;
};
static void dirbuf_add(fuse_req_t req, struct dirbuf *b, const char *name,
{
struct stat stbuf;
size_t oldsize = b->size;
b->size += fuse_add_direntry(req, NULL, 0, name, NULL, 0);
b->p = (char *) realloc(b->p, b->size);
memset(&stbuf, 0, sizeof(stbuf));
stbuf.st_ino = ino;
fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf,
b->size);
}
#define min(x, y) ((x) < (y) ? (x) : (y))
static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize,
off_t off, size_t maxsize)
{
if (off < bufsize)
return fuse_reply_buf(req, buf + off,
min(bufsize - off, maxsize));
else
return fuse_reply_buf(req, NULL, 0);
}
static void hello_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t off, struct fuse_file_info *fi)
{
(void) fi;
if (ino != 1)
fuse_reply_err(req, ENOTDIR);
else {
struct dirbuf b;
memset(&b, 0, sizeof(b));
dirbuf_add(req, &b, ".", 1);
dirbuf_add(req, &b, "..", 1);
dirbuf_add(req, &b, hello_name, 2);
reply_buf_limited(req, b.p, b.size, off, size);
free(b.p);
}
}
static void hello_ll_open(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
if (ino != 2)
fuse_reply_err(req, EISDIR);
else if ((fi->flags & 3) != O_RDONLY)
fuse_reply_err(req, EACCES);
else
fuse_reply_open(req, fi);
}
static void hello_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t off, struct fuse_file_info *fi)
{
(void) fi;
assert(ino == 2);
reply_buf_limited(req, hello_str, strlen(hello_str), off, size);
}
static struct fuse_lowlevel_ops hello_ll_oper = {
.lookup = hello_ll_lookup,
.getattr = hello_ll_getattr,
.readdir = hello_ll_readdir,
.open = hello_ll_open,
.read = hello_ll_read,
};
int main(int argc, char *argv[])
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
struct fuse_session *se;
struct fuse_cmdline_opts opts;
int ret = -1;
if (fuse_parse_cmdline(&args, &opts) != 0)
return 1;
if (opts.show_help) {
printf("usage: %s [options] <mountpoint>\n\n", argv[0]);
ret = 0;
goto err_out1;
} else if (opts.show_version) {
printf("FUSE library version %s\n", fuse_pkgversion());
ret = 0;
goto err_out1;
}
se = fuse_session_new(&args, &hello_ll_oper,
sizeof(hello_ll_oper), NULL);
if (se == NULL)
goto err_out1;
goto err_out2;
if (fuse_session_mount(se, opts.mountpoint) != 0)
goto err_out3;
fuse_daemonize(opts.foreground);
/* Block until ctrl+c or fusermount -u */
if (opts.singlethread)
ret = fuse_session_loop(se);
else
ret = fuse_session_loop_mt(se, opts.clone_fd);
err_out3:
err_out2:
err_out1:
free(opts.mountpoint);
return ret ? 1 : 0;
}
+

Definition in file hello_ll.c.

+
+ + + + diff --git a/doc/html/hello__ll_8c_source.html b/doc/html/hello__ll_8c_source.html new file mode 100644 index 0000000..63e1974 --- /dev/null +++ b/doc/html/hello__ll_8c_source.html @@ -0,0 +1,86 @@ + + + + + + + +libfuse: example/hello_ll.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
hello_ll.c
+
+
+Go to the documentation of this file.
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU GPL.
6  See the file COPYING.
7 */
8 
21 #define FUSE_USE_VERSION 31
22 
23 #include <fuse_lowlevel.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <assert.h>
31 
32 static const char *hello_str = "Hello World!\n";
33 static const char *hello_name = "hello";
34 
35 static int hello_stat(fuse_ino_t ino, struct stat *stbuf)
36 {
37  stbuf->st_ino = ino;
38  switch (ino) {
39  case 1:
40  stbuf->st_mode = S_IFDIR | 0755;
41  stbuf->st_nlink = 2;
42  break;
43 
44  case 2:
45  stbuf->st_mode = S_IFREG | 0444;
46  stbuf->st_nlink = 1;
47  stbuf->st_size = strlen(hello_str);
48  break;
49 
50  default:
51  return -1;
52  }
53  return 0;
54 }
55 
56 static void hello_ll_getattr(fuse_req_t req, fuse_ino_t ino,
57  struct fuse_file_info *fi)
58 {
59  struct stat stbuf;
60 
61  (void) fi;
62 
63  memset(&stbuf, 0, sizeof(stbuf));
64  if (hello_stat(ino, &stbuf) == -1)
65  fuse_reply_err(req, ENOENT);
66  else
67  fuse_reply_attr(req, &stbuf, 1.0);
68 }
69 
70 static void hello_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
71 {
72  struct fuse_entry_param e;
73 
74  if (parent != 1 || strcmp(name, hello_name) != 0)
75  fuse_reply_err(req, ENOENT);
76  else {
77  memset(&e, 0, sizeof(e));
78  e.ino = 2;
79  e.attr_timeout = 1.0;
80  e.entry_timeout = 1.0;
81  hello_stat(e.ino, &e.attr);
82 
83  fuse_reply_entry(req, &e);
84  }
85 }
86 
87 struct dirbuf {
88  char *p;
89  size_t size;
90 };
91 
92 static void dirbuf_add(fuse_req_t req, struct dirbuf *b, const char *name,
93  fuse_ino_t ino)
94 {
95  struct stat stbuf;
96  size_t oldsize = b->size;
97  b->size += fuse_add_direntry(req, NULL, 0, name, NULL, 0);
98  b->p = (char *) realloc(b->p, b->size);
99  memset(&stbuf, 0, sizeof(stbuf));
100  stbuf.st_ino = ino;
101  fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf,
102  b->size);
103 }
104 
105 #define min(x, y) ((x) < (y) ? (x) : (y))
106 
107 static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize,
108  off_t off, size_t maxsize)
109 {
110  if (off < bufsize)
111  return fuse_reply_buf(req, buf + off,
112  min(bufsize - off, maxsize));
113  else
114  return fuse_reply_buf(req, NULL, 0);
115 }
116 
117 static void hello_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
118  off_t off, struct fuse_file_info *fi)
119 {
120  (void) fi;
121 
122  if (ino != 1)
123  fuse_reply_err(req, ENOTDIR);
124  else {
125  struct dirbuf b;
126 
127  memset(&b, 0, sizeof(b));
128  dirbuf_add(req, &b, ".", 1);
129  dirbuf_add(req, &b, "..", 1);
130  dirbuf_add(req, &b, hello_name, 2);
131  reply_buf_limited(req, b.p, b.size, off, size);
132  free(b.p);
133  }
134 }
135 
136 static void hello_ll_open(fuse_req_t req, fuse_ino_t ino,
137  struct fuse_file_info *fi)
138 {
139  if (ino != 2)
140  fuse_reply_err(req, EISDIR);
141  else if ((fi->flags & 3) != O_RDONLY)
142  fuse_reply_err(req, EACCES);
143  else
144  fuse_reply_open(req, fi);
145 }
146 
147 static void hello_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size,
148  off_t off, struct fuse_file_info *fi)
149 {
150  (void) fi;
151 
152  assert(ino == 2);
153  reply_buf_limited(req, hello_str, strlen(hello_str), off, size);
154 }
155 
156 static struct fuse_lowlevel_ops hello_ll_oper = {
157  .lookup = hello_ll_lookup,
158  .getattr = hello_ll_getattr,
159  .readdir = hello_ll_readdir,
160  .open = hello_ll_open,
161  .read = hello_ll_read,
162 };
163 
164 int main(int argc, char *argv[])
165 {
166  struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
167  struct fuse_session *se;
168  struct fuse_cmdline_opts opts;
169  int ret = -1;
170 
171  if (fuse_parse_cmdline(&args, &opts) != 0)
172  return 1;
173  if (opts.show_help) {
174  printf("usage: %s [options] <mountpoint>\n\n", argv[0]);
177  ret = 0;
178  goto err_out1;
179  } else if (opts.show_version) {
180  printf("FUSE library version %s\n", fuse_pkgversion());
182  ret = 0;
183  goto err_out1;
184  }
185 
186  se = fuse_session_new(&args, &hello_ll_oper,
187  sizeof(hello_ll_oper), NULL);
188  if (se == NULL)
189  goto err_out1;
190 
191  if (fuse_set_signal_handlers(se) != 0)
192  goto err_out2;
193 
194  if (fuse_session_mount(se, opts.mountpoint) != 0)
195  goto err_out3;
196 
197  fuse_daemonize(opts.foreground);
198 
199  /* Block until ctrl+c or fusermount -u */
200  if (opts.singlethread)
201  ret = fuse_session_loop(se);
202  else
203  ret = fuse_session_loop_mt(se, opts.clone_fd);
204 
206 err_out3:
208 err_out2:
210 err_out1:
211  free(opts.mountpoint);
212  fuse_opt_free_args(&args);
213 
214  return ret ? 1 : 0;
215 }
void fuse_session_destroy(struct fuse_session *se)
+
int fuse_reply_err(fuse_req_t req, int err)
+
struct fuse_session * fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)
+
int fuse_session_loop(struct fuse_session *se)
Definition: fuse_loop.c:19
+
void fuse_lowlevel_help(void)
+
int fuse_daemonize(int foreground)
Definition: helper.c:225
+
int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
+
struct fuse_req * fuse_req_t
Definition: fuse_lowlevel.h:49
+
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)
+
Definition: fuse_lowlevel.h:59
+
int fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts)
Definition: helper.c:202
+
void fuse_cmdline_help(void)
Definition: helper.c:129
+
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
+
int fuse_set_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:62
+
void fuse_remove_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:79
+ +
void fuse_lowlevel_version(void)
+ +
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:33
+
int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
+
void fuse_session_unmount(struct fuse_session *se)
+
void(* lookup)(fuse_req_t req, fuse_ino_t parent, const char *name)
+
uint64_t fuse_ino_t
Definition: fuse_lowlevel.h:46
+
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi)
+ + + +
const char * fuse_pkgversion(void)
Definition: fuse.c:5071
+
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
+
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
+
+ + + + diff --git a/doc/html/helper_8c_source.html b/doc/html/helper_8c_source.html new file mode 100644 index 0000000..4462ff9 --- /dev/null +++ b/doc/html/helper_8c_source.html @@ -0,0 +1,107 @@ + + + + + + + +libfuse: lib/helper.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
helper.c
+
+
+
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  Helper functions to create (simple) standalone programs. With the
6  aid of these functions it should be possible to create full FUSE
7  file system by implementing nothing but the request handlers.
8 
9  This program can be distributed under the terms of the GNU LGPLv2.
10  See the file COPYING.LIB.
11 */
12 
13 #include "config.h"
14 #include "fuse_i.h"
15 #include "fuse_misc.h"
16 #include "fuse_opt.h"
17 #include "fuse_lowlevel.h"
18 #include "mount_util.h"
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stddef.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <limits.h>
26 #include <errno.h>
27 #include <sys/param.h>
28 
29 #define FUSE_HELPER_OPT(t, p) \
30  { t, offsetof(struct fuse_cmdline_opts, p), 1 }
31 
32 static const struct fuse_opt fuse_helper_opts[] = {
33  FUSE_HELPER_OPT("-h", show_help),
34  FUSE_HELPER_OPT("--help", show_help),
35  FUSE_HELPER_OPT("-V", show_version),
36  FUSE_HELPER_OPT("--version", show_version),
37  FUSE_HELPER_OPT("-d", debug),
38  FUSE_HELPER_OPT("debug", debug),
39  FUSE_HELPER_OPT("-d", foreground),
40  FUSE_HELPER_OPT("debug", foreground),
43  FUSE_HELPER_OPT("-f", foreground),
44  FUSE_HELPER_OPT("-s", singlethread),
45  FUSE_HELPER_OPT("fsname=", nodefault_subtype),
46  FUSE_OPT_KEY("fsname=", FUSE_OPT_KEY_KEEP),
47 #ifndef __FreeBSD__
48  FUSE_HELPER_OPT("subtype=", nodefault_subtype),
49  FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP),
50 #endif
51  FUSE_HELPER_OPT("clone_fd", clone_fd),
52  FUSE_HELPER_OPT("max_idle_threads=%u", max_idle_threads),
54 };
55 
56 struct fuse_conn_info_opts {
57  int atomic_o_trunc;
58  int no_remote_posix_lock;
59  int no_remote_flock;
60  int splice_write;
61  int splice_move;
62  int splice_read;
63  int no_splice_write;
64  int no_splice_move;
65  int no_splice_read;
66  int auto_inval_data;
67  int no_auto_inval_data;
68  int no_readdirplus;
69  int no_readdirplus_auto;
70  int async_dio;
71  int no_async_dio;
72  int writeback_cache;
73  int no_writeback_cache;
74  int async_read;
75  int sync_read;
76  unsigned max_write;
77  unsigned max_readahead;
78  unsigned max_background;
79  unsigned congestion_threshold;
80  unsigned time_gran;
81  int set_max_write;
82  int set_max_readahead;
83  int set_max_background;
84  int set_congestion_threshold;
85  int set_time_gran;
86 };
87 
88 #define CONN_OPTION(t, p, v) \
89  { t, offsetof(struct fuse_conn_info_opts, p), v }
90 static const struct fuse_opt conn_info_opt_spec[] = {
91  CONN_OPTION("max_write=%u", max_write, 0),
92  CONN_OPTION("max_write=", set_max_write, 1),
93  CONN_OPTION("max_readahead=%u", max_readahead, 0),
94  CONN_OPTION("max_readahead=", set_max_readahead, 1),
95  CONN_OPTION("max_background=%u", max_background, 0),
96  CONN_OPTION("max_background=", set_max_background, 1),
97  CONN_OPTION("congestion_threshold=%u", congestion_threshold, 0),
98  CONN_OPTION("congestion_threshold=", set_congestion_threshold, 1),
99  CONN_OPTION("sync_read", sync_read, 1),
100  CONN_OPTION("async_read", async_read, 1),
101  CONN_OPTION("atomic_o_trunc", atomic_o_trunc, 1),
102  CONN_OPTION("no_remote_lock", no_remote_posix_lock, 1),
103  CONN_OPTION("no_remote_lock", no_remote_flock, 1),
104  CONN_OPTION("no_remote_flock", no_remote_flock, 1),
105  CONN_OPTION("no_remote_posix_lock", no_remote_posix_lock, 1),
106  CONN_OPTION("splice_write", splice_write, 1),
107  CONN_OPTION("no_splice_write", no_splice_write, 1),
108  CONN_OPTION("splice_move", splice_move, 1),
109  CONN_OPTION("no_splice_move", no_splice_move, 1),
110  CONN_OPTION("splice_read", splice_read, 1),
111  CONN_OPTION("no_splice_read", no_splice_read, 1),
112  CONN_OPTION("auto_inval_data", auto_inval_data, 1),
113  CONN_OPTION("no_auto_inval_data", no_auto_inval_data, 1),
114  CONN_OPTION("readdirplus=no", no_readdirplus, 1),
115  CONN_OPTION("readdirplus=yes", no_readdirplus, 0),
116  CONN_OPTION("readdirplus=yes", no_readdirplus_auto, 1),
117  CONN_OPTION("readdirplus=auto", no_readdirplus, 0),
118  CONN_OPTION("readdirplus=auto", no_readdirplus_auto, 0),
119  CONN_OPTION("async_dio", async_dio, 1),
120  CONN_OPTION("no_async_dio", no_async_dio, 1),
121  CONN_OPTION("writeback_cache", writeback_cache, 1),
122  CONN_OPTION("no_writeback_cache", no_writeback_cache, 1),
123  CONN_OPTION("time_gran=%u", time_gran, 0),
124  CONN_OPTION("time_gran=", set_time_gran, 1),
126 };
127 
128 
130 {
131  printf(" -h --help print help\n"
132  " -V --version print version\n"
133  " -d -o debug enable debug output (implies -f)\n"
134  " -f foreground operation\n"
135  " -s disable multi-threaded operation\n"
136  " -o clone_fd use separate fuse device fd for each thread\n"
137  " (may improve performance)\n"
138  " -o max_idle_threads the maximum number of idle worker threads\n"
139  " allowed (default: 10)\n");
140 }
141 
142 static int fuse_helper_opt_proc(void *data, const char *arg, int key,
143  struct fuse_args *outargs)
144 {
145  (void) outargs;
146  struct fuse_cmdline_opts *opts = data;
147 
148  switch (key) {
149  case FUSE_OPT_KEY_NONOPT:
150  if (!opts->mountpoint) {
151  if (fuse_mnt_parse_fuse_fd(arg) != -1) {
152  return fuse_opt_add_opt(&opts->mountpoint, arg);
153  }
154 
155  char mountpoint[PATH_MAX] = "";
156  if (realpath(arg, mountpoint) == NULL) {
157  fprintf(stderr,
158  "fuse: bad mount point `%s': %s\n",
159  arg, strerror(errno));
160  return -1;
161  }
162  return fuse_opt_add_opt(&opts->mountpoint, mountpoint);
163  } else {
164  fprintf(stderr, "fuse: invalid argument `%s'\n", arg);
165  return -1;
166  }
167 
168  default:
169  /* Pass through unknown options */
170  return 1;
171  }
172 }
173 
174 /* Under FreeBSD, there is no subtype option so this
175  function actually sets the fsname */
176 static int add_default_subtype(const char *progname, struct fuse_args *args)
177 {
178  int res;
179  char *subtype_opt;
180 
181  const char *basename = strrchr(progname, '/');
182  if (basename == NULL)
183  basename = progname;
184  else if (basename[1] != '\0')
185  basename++;
186 
187  subtype_opt = (char *) malloc(strlen(basename) + 64);
188  if (subtype_opt == NULL) {
189  fprintf(stderr, "fuse: memory allocation failed\n");
190  return -1;
191  }
192 #ifdef __FreeBSD__
193  sprintf(subtype_opt, "-ofsname=%s", basename);
194 #else
195  sprintf(subtype_opt, "-osubtype=%s", basename);
196 #endif
197  res = fuse_opt_add_arg(args, subtype_opt);
198  free(subtype_opt);
199  return res;
200 }
201 
202 int fuse_parse_cmdline(struct fuse_args *args,
203  struct fuse_cmdline_opts *opts)
204 {
205  memset(opts, 0, sizeof(struct fuse_cmdline_opts));
206 
207  opts->max_idle_threads = 10;
208 
209  if (fuse_opt_parse(args, opts, fuse_helper_opts,
210  fuse_helper_opt_proc) == -1)
211  return -1;
212 
213  /* *Linux*: if neither -o subtype nor -o fsname are specified,
214  set subtype to program's basename.
215  *FreeBSD*: if fsname is not specified, set to program's
216  basename. */
217  if (!opts->nodefault_subtype)
218  if (add_default_subtype(args->argv[0], args) == -1)
219  return -1;
220 
221  return 0;
222 }
223 
224 
225 int fuse_daemonize(int foreground)
226 {
227  if (!foreground) {
228  int nullfd;
229  int waiter[2];
230  char completed;
231 
232  if (pipe(waiter)) {
233  perror("fuse_daemonize: pipe");
234  return -1;
235  }
236 
237  /*
238  * demonize current process by forking it and killing the
239  * parent. This makes current process as a child of 'init'.
240  */
241  switch(fork()) {
242  case -1:
243  perror("fuse_daemonize: fork");
244  return -1;
245  case 0:
246  break;
247  default:
248  (void) read(waiter[0], &completed, sizeof(completed));
249  _exit(0);
250  }
251 
252  if (setsid() == -1) {
253  perror("fuse_daemonize: setsid");
254  return -1;
255  }
256 
257  (void) chdir("/");
258 
259  nullfd = open("/dev/null", O_RDWR, 0);
260  if (nullfd != -1) {
261  (void) dup2(nullfd, 0);
262  (void) dup2(nullfd, 1);
263  (void) dup2(nullfd, 2);
264  if (nullfd > 2)
265  close(nullfd);
266  }
267 
268  /* Propagate completion of daemon initialization */
269  completed = 1;
270  (void) write(waiter[1], &completed, sizeof(completed));
271  close(waiter[0]);
272  close(waiter[1]);
273  } else {
274  (void) chdir("/");
275  }
276  return 0;
277 }
278 
279 int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
280  size_t op_size, void *user_data)
281 {
282  struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
283  struct fuse *fuse;
284  struct fuse_cmdline_opts opts;
285  int res;
286 
287  if (fuse_parse_cmdline(&args, &opts) != 0)
288  return 1;
289 
290  if (opts.show_version) {
291  printf("FUSE library version %s\n", PACKAGE_VERSION);
293  res = 0;
294  goto out1;
295  }
296 
297  if (opts.show_help) {
298  if(args.argv[0][0] != '\0')
299  printf("usage: %s [options] <mountpoint>\n\n",
300  args.argv[0]);
301  printf("FUSE options:\n");
303  fuse_lib_help(&args);
304  res = 0;
305  goto out1;
306  }
307 
308  if (!opts.show_help &&
309  !opts.mountpoint) {
310  fprintf(stderr, "error: no mountpoint specified\n");
311  res = 2;
312  goto out1;
313  }
314 
315 
316  fuse = fuse_new_31(&args, op, op_size, user_data);
317  if (fuse == NULL) {
318  res = 3;
319  goto out1;
320  }
321 
322  if (fuse_mount(fuse,opts.mountpoint) != 0) {
323  res = 4;
324  goto out2;
325  }
326 
327  if (fuse_daemonize(opts.foreground) != 0) {
328  res = 5;
329  goto out3;
330  }
331 
332  struct fuse_session *se = fuse_get_session(fuse);
333  if (fuse_set_signal_handlers(se) != 0) {
334  res = 6;
335  goto out3;
336  }
337 
338  if (opts.singlethread)
339  res = fuse_loop(fuse);
340  else {
341  struct fuse_loop_config loop_config;
342  loop_config.clone_fd = opts.clone_fd;
343  loop_config.max_idle_threads = opts.max_idle_threads;
344  res = fuse_loop_mt_32(fuse, &loop_config);
345  }
346  if (res)
347  res = 7;
348 
350 out3:
351  fuse_unmount(fuse);
352 out2:
353  fuse_destroy(fuse);
354 out1:
355  free(opts.mountpoint);
356  fuse_opt_free_args(&args);
357  return res;
358 }
359 
360 
361 void fuse_apply_conn_info_opts(struct fuse_conn_info_opts *opts,
362  struct fuse_conn_info *conn)
363 {
364  if(opts->set_max_write)
365  conn->max_write = opts->max_write;
366  if(opts->set_max_background)
367  conn->max_background = opts->max_background;
368  if(opts->set_congestion_threshold)
369  conn->congestion_threshold = opts->congestion_threshold;
370  if(opts->set_time_gran)
371  conn->time_gran = opts->time_gran;
372  if(opts->set_max_readahead)
373  conn->max_readahead = opts->max_readahead;
374 
375 #define LL_ENABLE(cond,cap) \
376  if (cond) conn->want |= (cap)
377 #define LL_DISABLE(cond,cap) \
378  if (cond) conn->want &= ~(cap)
379 
380  LL_ENABLE(opts->splice_read, FUSE_CAP_SPLICE_READ);
381  LL_DISABLE(opts->no_splice_read, FUSE_CAP_SPLICE_READ);
382 
383  LL_ENABLE(opts->splice_write, FUSE_CAP_SPLICE_WRITE);
384  LL_DISABLE(opts->no_splice_write, FUSE_CAP_SPLICE_WRITE);
385 
386  LL_ENABLE(opts->splice_move, FUSE_CAP_SPLICE_MOVE);
387  LL_DISABLE(opts->no_splice_move, FUSE_CAP_SPLICE_MOVE);
388 
389  LL_ENABLE(opts->auto_inval_data, FUSE_CAP_AUTO_INVAL_DATA);
390  LL_DISABLE(opts->no_auto_inval_data, FUSE_CAP_AUTO_INVAL_DATA);
391 
392  LL_DISABLE(opts->no_readdirplus, FUSE_CAP_READDIRPLUS);
393  LL_DISABLE(opts->no_readdirplus_auto, FUSE_CAP_READDIRPLUS_AUTO);
394 
395  LL_ENABLE(opts->async_dio, FUSE_CAP_ASYNC_DIO);
396  LL_DISABLE(opts->no_async_dio, FUSE_CAP_ASYNC_DIO);
397 
398  LL_ENABLE(opts->writeback_cache, FUSE_CAP_WRITEBACK_CACHE);
399  LL_DISABLE(opts->no_writeback_cache, FUSE_CAP_WRITEBACK_CACHE);
400 
401  LL_ENABLE(opts->async_read, FUSE_CAP_ASYNC_READ);
402  LL_DISABLE(opts->sync_read, FUSE_CAP_ASYNC_READ);
403 
404  LL_DISABLE(opts->no_remote_posix_lock, FUSE_CAP_POSIX_LOCKS);
405  LL_DISABLE(opts->no_remote_flock, FUSE_CAP_FLOCK_LOCKS);
406 }
407 
408 struct fuse_conn_info_opts* fuse_parse_conn_info_opts(struct fuse_args *args)
409 {
410  struct fuse_conn_info_opts *opts;
411 
412  opts = calloc(1, sizeof(struct fuse_conn_info_opts));
413  if(opts == NULL) {
414  fprintf(stderr, "calloc failed\n");
415  return NULL;
416  }
417  if(fuse_opt_parse(args, opts, conn_info_opt_spec, NULL) == -1) {
418  free(opts);
419  return NULL;
420  }
421  return opts;
422 }
423 
424 int fuse_open_channel(const char *mountpoint, const char* options)
425 {
426  struct mount_opts *opts = NULL;
427  int fd = -1;
428  const char *argv[] = { "", "-o", options };
429  int argc = sizeof(argv) / sizeof(argv[0]);
430  struct fuse_args args = FUSE_ARGS_INIT(argc, (char**) argv);
431 
432  opts = parse_mount_opts(&args);
433  if (opts == NULL)
434  return -1;
435 
436  fd = fuse_kern_mount(mountpoint, opts);
437  destroy_mount_opts(opts);
438 
439  return fd;
440 }
+
unsigned max_write
Definition: fuse_common.h:357
+
int fuse_daemonize(int foreground)
Definition: helper.c:225
+
#define FUSE_CAP_ASYNC_READ
Definition: fuse_common.h:120
+
unsigned int max_idle_threads
Definition: fuse_common.h:103
+
int fuse_loop(struct fuse *f)
Definition: fuse.c:4516
+
unsigned max_background
Definition: fuse_common.h:419
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
int fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts)
Definition: helper.c:202
+
void fuse_cmdline_help(void)
Definition: helper.c:129
+
#define FUSE_CAP_READDIRPLUS_AUTO
Definition: fuse_common.h:246
+
int fuse_set_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:62
+
#define FUSE_CAP_SPLICE_WRITE
Definition: fuse_common.h:160
+
void fuse_remove_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:79
+
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:54
+
void fuse_destroy(struct fuse *f)
Definition: fuse.c:5007
+
struct fuse_conn_info_opts * fuse_parse_conn_info_opts(struct fuse_args *args)
Definition: helper.c:408
+
void fuse_lowlevel_version(void)
+ +
void fuse_apply_conn_info_opts(struct fuse_conn_info_opts *opts, struct fuse_conn_info *conn)
Definition: helper.c:361
+ +
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:33
+
#define FUSE_CAP_SPLICE_MOVE
Definition: fuse_common.h:168
+
int fuse_open_channel(const char *mountpoint, const char *options)
Definition: helper.c:424
+
#define FUSE_CAP_AUTO_INVAL_DATA
Definition: fuse_common.h:219
+ +
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98
+
#define FUSE_CAP_SPLICE_READ
Definition: fuse_common.h:177
+
#define FUSE_OPT_END
Definition: fuse_opt.h:104
+
unsigned congestion_threshold
Definition: fuse_common.h:429
+
struct fuse_session * fuse_get_session(struct fuse *f)
Definition: fuse.c:4459
+
#define FUSE_OPT_KEY_KEEP
Definition: fuse_opt.h:145
+
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, size_t op_size, void *private_data)
Definition: helper.c:279
+
int fuse_opt_add_opt(char **opts, const char *opt)
Definition: fuse_opt.c:138
+
#define FUSE_CAP_FLOCK_LOCKS
Definition: fuse_common.h:190
+
unsigned max_readahead
Definition: fuse_common.h:376
+
void fuse_lib_help(struct fuse_args *args)
Definition: fuse.c:4650
+
#define FUSE_OPT_KEY_NONOPT
Definition: fuse_opt.h:137
+
char ** argv
Definition: fuse_opt.h:114
+
#define FUSE_CAP_ASYNC_DIO
Definition: fuse_common.h:257
+
#define FUSE_CAP_WRITEBACK_CACHE
Definition: fuse_common.h:266
+
int fuse_mount(struct fuse *f, const char *mountpoint)
Definition: fuse.c:5057
+
#define FUSE_CAP_POSIX_LOCKS
Definition: fuse_common.h:128
+ + +
void fuse_unmount(struct fuse *f)
Definition: fuse.c:5062
+ +
#define FUSE_CAP_READDIRPLUS
Definition: fuse_common.h:227
+
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
+ +
unsigned time_gran
Definition: fuse_common.h:446
+
+ + + + diff --git a/doc/html/iconv_8c_source.html b/doc/html/iconv_8c_source.html new file mode 100644 index 0000000..a2eb935 --- /dev/null +++ b/doc/html/iconv_8c_source.html @@ -0,0 +1,75 @@ + + + + + + + +libfuse: lib/modules/iconv.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
iconv.c
+
+
+
1 /*
2  fuse iconv module: file name charset conversion
3  Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu>
4 
5  This program can be distributed under the terms of the GNU LGPLv2.
6  See the file COPYING.LIB
7 */
8 
9 #include <config.h>
10 
11 #include <fuse.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <stddef.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <iconv.h>
18 #include <pthread.h>
19 #include <locale.h>
20 #include <langinfo.h>
21 
22 struct iconv {
23  struct fuse_fs *next;
24  pthread_mutex_t lock;
25  char *from_code;
26  char *to_code;
27  iconv_t tofs;
28  iconv_t fromfs;
29 };
30 
31 struct iconv_dh {
32  struct iconv *ic;
33  void *prev_buf;
34  fuse_fill_dir_t prev_filler;
35 };
36 
37 static struct iconv *iconv_get(void)
38 {
40 }
41 
42 static int iconv_convpath(struct iconv *ic, const char *path, char **newpathp,
43  int fromfs)
44 {
45  size_t pathlen;
46  size_t newpathlen;
47  char *newpath;
48  size_t plen;
49  char *p;
50  size_t res;
51  int err;
52 
53  if (path == NULL) {
54  *newpathp = NULL;
55  return 0;
56  }
57 
58  pathlen = strlen(path);
59  newpathlen = pathlen * 4;
60  newpath = malloc(newpathlen + 1);
61  if (!newpath)
62  return -ENOMEM;
63 
64  plen = newpathlen;
65  p = newpath;
66  pthread_mutex_lock(&ic->lock);
67  do {
68  res = iconv(fromfs ? ic->fromfs : ic->tofs, (char **) &path,
69  &pathlen, &p, &plen);
70  if (res == (size_t) -1) {
71  char *tmp;
72  size_t inc;
73 
74  err = -EILSEQ;
75  if (errno != E2BIG)
76  goto err;
77 
78  inc = (pathlen + 1) * 4;
79  newpathlen += inc;
80  tmp = realloc(newpath, newpathlen + 1);
81  err = -ENOMEM;
82  if (!tmp)
83  goto err;
84 
85  p = tmp + (p - newpath);
86  plen += inc;
87  newpath = tmp;
88  }
89  } while (res == (size_t) -1);
90  pthread_mutex_unlock(&ic->lock);
91  *p = '\0';
92  *newpathp = newpath;
93  return 0;
94 
95 err:
96  iconv(fromfs ? ic->fromfs : ic->tofs, NULL, NULL, NULL, NULL);
97  pthread_mutex_unlock(&ic->lock);
98  free(newpath);
99  return err;
100 }
101 
102 static int iconv_getattr(const char *path, struct stat *stbuf,
103  struct fuse_file_info *fi)
104 {
105  struct iconv *ic = iconv_get();
106  char *newpath;
107  int err = iconv_convpath(ic, path, &newpath, 0);
108  if (!err) {
109  err = fuse_fs_getattr(ic->next, newpath, stbuf, fi);
110  free(newpath);
111  }
112  return err;
113 }
114 
115 static int iconv_access(const char *path, int mask)
116 {
117  struct iconv *ic = iconv_get();
118  char *newpath;
119  int err = iconv_convpath(ic, path, &newpath, 0);
120  if (!err) {
121  err = fuse_fs_access(ic->next, newpath, mask);
122  free(newpath);
123  }
124  return err;
125 }
126 
127 static int iconv_readlink(const char *path, char *buf, size_t size)
128 {
129  struct iconv *ic = iconv_get();
130  char *newpath;
131  int err = iconv_convpath(ic, path, &newpath, 0);
132  if (!err) {
133  err = fuse_fs_readlink(ic->next, newpath, buf, size);
134  if (!err) {
135  char *newlink;
136  err = iconv_convpath(ic, buf, &newlink, 1);
137  if (!err) {
138  strncpy(buf, newlink, size - 1);
139  buf[size - 1] = '\0';
140  free(newlink);
141  }
142  }
143  free(newpath);
144  }
145  return err;
146 }
147 
148 static int iconv_opendir(const char *path, struct fuse_file_info *fi)
149 {
150  struct iconv *ic = iconv_get();
151  char *newpath;
152  int err = iconv_convpath(ic, path, &newpath, 0);
153  if (!err) {
154  err = fuse_fs_opendir(ic->next, newpath, fi);
155  free(newpath);
156  }
157  return err;
158 }
159 
160 static int iconv_dir_fill(void *buf, const char *name,
161  const struct stat *stbuf, off_t off,
162  enum fuse_fill_dir_flags flags)
163 {
164  struct iconv_dh *dh = buf;
165  char *newname;
166  int res = 0;
167  if (iconv_convpath(dh->ic, name, &newname, 1) == 0) {
168  res = dh->prev_filler(dh->prev_buf, newname, stbuf, off, flags);
169  free(newname);
170  }
171  return res;
172 }
173 
174 static int iconv_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
175  off_t offset, struct fuse_file_info *fi,
176  enum fuse_readdir_flags flags)
177 {
178  struct iconv *ic = iconv_get();
179  char *newpath;
180  int err = iconv_convpath(ic, path, &newpath, 0);
181  if (!err) {
182  struct iconv_dh dh;
183  dh.ic = ic;
184  dh.prev_buf = buf;
185  dh.prev_filler = filler;
186  err = fuse_fs_readdir(ic->next, newpath, &dh, iconv_dir_fill,
187  offset, fi, flags);
188  free(newpath);
189  }
190  return err;
191 }
192 
193 static int iconv_releasedir(const char *path, struct fuse_file_info *fi)
194 {
195  struct iconv *ic = iconv_get();
196  char *newpath;
197  int err = iconv_convpath(ic, path, &newpath, 0);
198  if (!err) {
199  err = fuse_fs_releasedir(ic->next, newpath, fi);
200  free(newpath);
201  }
202  return err;
203 }
204 
205 static int iconv_mknod(const char *path, mode_t mode, dev_t rdev)
206 {
207  struct iconv *ic = iconv_get();
208  char *newpath;
209  int err = iconv_convpath(ic, path, &newpath, 0);
210  if (!err) {
211  err = fuse_fs_mknod(ic->next, newpath, mode, rdev);
212  free(newpath);
213  }
214  return err;
215 }
216 
217 static int iconv_mkdir(const char *path, mode_t mode)
218 {
219  struct iconv *ic = iconv_get();
220  char *newpath;
221  int err = iconv_convpath(ic, path, &newpath, 0);
222  if (!err) {
223  err = fuse_fs_mkdir(ic->next, newpath, mode);
224  free(newpath);
225  }
226  return err;
227 }
228 
229 static int iconv_unlink(const char *path)
230 {
231  struct iconv *ic = iconv_get();
232  char *newpath;
233  int err = iconv_convpath(ic, path, &newpath, 0);
234  if (!err) {
235  err = fuse_fs_unlink(ic->next, newpath);
236  free(newpath);
237  }
238  return err;
239 }
240 
241 static int iconv_rmdir(const char *path)
242 {
243  struct iconv *ic = iconv_get();
244  char *newpath;
245  int err = iconv_convpath(ic, path, &newpath, 0);
246  if (!err) {
247  err = fuse_fs_rmdir(ic->next, newpath);
248  free(newpath);
249  }
250  return err;
251 }
252 
253 static int iconv_symlink(const char *from, const char *to)
254 {
255  struct iconv *ic = iconv_get();
256  char *newfrom;
257  char *newto;
258  int err = iconv_convpath(ic, from, &newfrom, 0);
259  if (!err) {
260  err = iconv_convpath(ic, to, &newto, 0);
261  if (!err) {
262  err = fuse_fs_symlink(ic->next, newfrom, newto);
263  free(newto);
264  }
265  free(newfrom);
266  }
267  return err;
268 }
269 
270 static int iconv_rename(const char *from, const char *to, unsigned int flags)
271 {
272  struct iconv *ic = iconv_get();
273  char *newfrom;
274  char *newto;
275  int err = iconv_convpath(ic, from, &newfrom, 0);
276  if (!err) {
277  err = iconv_convpath(ic, to, &newto, 0);
278  if (!err) {
279  err = fuse_fs_rename(ic->next, newfrom, newto, flags);
280  free(newto);
281  }
282  free(newfrom);
283  }
284  return err;
285 }
286 
287 static int iconv_link(const char *from, const char *to)
288 {
289  struct iconv *ic = iconv_get();
290  char *newfrom;
291  char *newto;
292  int err = iconv_convpath(ic, from, &newfrom, 0);
293  if (!err) {
294  err = iconv_convpath(ic, to, &newto, 0);
295  if (!err) {
296  err = fuse_fs_link(ic->next, newfrom, newto);
297  free(newto);
298  }
299  free(newfrom);
300  }
301  return err;
302 }
303 
304 static int iconv_chmod(const char *path, mode_t mode,
305  struct fuse_file_info *fi)
306 {
307  struct iconv *ic = iconv_get();
308  char *newpath;
309  int err = iconv_convpath(ic, path, &newpath, 0);
310  if (!err) {
311  err = fuse_fs_chmod(ic->next, newpath, mode, fi);
312  free(newpath);
313  }
314  return err;
315 }
316 
317 static int iconv_chown(const char *path, uid_t uid, gid_t gid,
318  struct fuse_file_info *fi)
319 {
320  struct iconv *ic = iconv_get();
321  char *newpath;
322  int err = iconv_convpath(ic, path, &newpath, 0);
323  if (!err) {
324  err = fuse_fs_chown(ic->next, newpath, uid, gid, fi);
325  free(newpath);
326  }
327  return err;
328 }
329 
330 static int iconv_truncate(const char *path, off_t size,
331  struct fuse_file_info *fi)
332 {
333  struct iconv *ic = iconv_get();
334  char *newpath;
335  int err = iconv_convpath(ic, path, &newpath, 0);
336  if (!err) {
337  err = fuse_fs_truncate(ic->next, newpath, size, fi);
338  free(newpath);
339  }
340  return err;
341 }
342 
343 static int iconv_utimens(const char *path, const struct timespec ts[2],
344  struct fuse_file_info *fi)
345 {
346  struct iconv *ic = iconv_get();
347  char *newpath;
348  int err = iconv_convpath(ic, path, &newpath, 0);
349  if (!err) {
350  err = fuse_fs_utimens(ic->next, newpath, ts, fi);
351  free(newpath);
352  }
353  return err;
354 }
355 
356 static int iconv_create(const char *path, mode_t mode,
357  struct fuse_file_info *fi)
358 {
359  struct iconv *ic = iconv_get();
360  char *newpath;
361  int err = iconv_convpath(ic, path, &newpath, 0);
362  if (!err) {
363  err = fuse_fs_create(ic->next, newpath, mode, fi);
364  free(newpath);
365  }
366  return err;
367 }
368 
369 static int iconv_open_file(const char *path, struct fuse_file_info *fi)
370 {
371  struct iconv *ic = iconv_get();
372  char *newpath;
373  int err = iconv_convpath(ic, path, &newpath, 0);
374  if (!err) {
375  err = fuse_fs_open(ic->next, newpath, fi);
376  free(newpath);
377  }
378  return err;
379 }
380 
381 static int iconv_read_buf(const char *path, struct fuse_bufvec **bufp,
382  size_t size, off_t offset, struct fuse_file_info *fi)
383 {
384  struct iconv *ic = iconv_get();
385  char *newpath;
386  int err = iconv_convpath(ic, path, &newpath, 0);
387  if (!err) {
388  err = fuse_fs_read_buf(ic->next, newpath, bufp, size, offset, fi);
389  free(newpath);
390  }
391  return err;
392 }
393 
394 static int iconv_write_buf(const char *path, struct fuse_bufvec *buf,
395  off_t offset, struct fuse_file_info *fi)
396 {
397  struct iconv *ic = iconv_get();
398  char *newpath;
399  int err = iconv_convpath(ic, path, &newpath, 0);
400  if (!err) {
401  err = fuse_fs_write_buf(ic->next, newpath, buf, offset, fi);
402  free(newpath);
403  }
404  return err;
405 }
406 
407 static int iconv_statfs(const char *path, struct statvfs *stbuf)
408 {
409  struct iconv *ic = iconv_get();
410  char *newpath;
411  int err = iconv_convpath(ic, path, &newpath, 0);
412  if (!err) {
413  err = fuse_fs_statfs(ic->next, newpath, stbuf);
414  free(newpath);
415  }
416  return err;
417 }
418 
419 static int iconv_flush(const char *path, struct fuse_file_info *fi)
420 {
421  struct iconv *ic = iconv_get();
422  char *newpath;
423  int err = iconv_convpath(ic, path, &newpath, 0);
424  if (!err) {
425  err = fuse_fs_flush(ic->next, newpath, fi);
426  free(newpath);
427  }
428  return err;
429 }
430 
431 static int iconv_release(const char *path, struct fuse_file_info *fi)
432 {
433  struct iconv *ic = iconv_get();
434  char *newpath;
435  int err = iconv_convpath(ic, path, &newpath, 0);
436  if (!err) {
437  err = fuse_fs_release(ic->next, newpath, fi);
438  free(newpath);
439  }
440  return err;
441 }
442 
443 static int iconv_fsync(const char *path, int isdatasync,
444  struct fuse_file_info *fi)
445 {
446  struct iconv *ic = iconv_get();
447  char *newpath;
448  int err = iconv_convpath(ic, path, &newpath, 0);
449  if (!err) {
450  err = fuse_fs_fsync(ic->next, newpath, isdatasync, fi);
451  free(newpath);
452  }
453  return err;
454 }
455 
456 static int iconv_fsyncdir(const char *path, int isdatasync,
457  struct fuse_file_info *fi)
458 {
459  struct iconv *ic = iconv_get();
460  char *newpath;
461  int err = iconv_convpath(ic, path, &newpath, 0);
462  if (!err) {
463  err = fuse_fs_fsyncdir(ic->next, newpath, isdatasync, fi);
464  free(newpath);
465  }
466  return err;
467 }
468 
469 static int iconv_setxattr(const char *path, const char *name,
470  const char *value, size_t size, int flags)
471 {
472  struct iconv *ic = iconv_get();
473  char *newpath;
474  int err = iconv_convpath(ic, path, &newpath, 0);
475  if (!err) {
476  err = fuse_fs_setxattr(ic->next, newpath, name, value, size,
477  flags);
478  free(newpath);
479  }
480  return err;
481 }
482 
483 static int iconv_getxattr(const char *path, const char *name, char *value,
484  size_t size)
485 {
486  struct iconv *ic = iconv_get();
487  char *newpath;
488  int err = iconv_convpath(ic, path, &newpath, 0);
489  if (!err) {
490  err = fuse_fs_getxattr(ic->next, newpath, name, value, size);
491  free(newpath);
492  }
493  return err;
494 }
495 
496 static int iconv_listxattr(const char *path, char *list, size_t size)
497 {
498  struct iconv *ic = iconv_get();
499  char *newpath;
500  int err = iconv_convpath(ic, path, &newpath, 0);
501  if (!err) {
502  err = fuse_fs_listxattr(ic->next, newpath, list, size);
503  free(newpath);
504  }
505  return err;
506 }
507 
508 static int iconv_removexattr(const char *path, const char *name)
509 {
510  struct iconv *ic = iconv_get();
511  char *newpath;
512  int err = iconv_convpath(ic, path, &newpath, 0);
513  if (!err) {
514  err = fuse_fs_removexattr(ic->next, newpath, name);
515  free(newpath);
516  }
517  return err;
518 }
519 
520 static int iconv_lock(const char *path, struct fuse_file_info *fi, int cmd,
521  struct flock *lock)
522 {
523  struct iconv *ic = iconv_get();
524  char *newpath;
525  int err = iconv_convpath(ic, path, &newpath, 0);
526  if (!err) {
527  err = fuse_fs_lock(ic->next, newpath, fi, cmd, lock);
528  free(newpath);
529  }
530  return err;
531 }
532 
533 static int iconv_flock(const char *path, struct fuse_file_info *fi, int op)
534 {
535  struct iconv *ic = iconv_get();
536  char *newpath;
537  int err = iconv_convpath(ic, path, &newpath, 0);
538  if (!err) {
539  err = fuse_fs_flock(ic->next, newpath, fi, op);
540  free(newpath);
541  }
542  return err;
543 }
544 
545 static int iconv_bmap(const char *path, size_t blocksize, uint64_t *idx)
546 {
547  struct iconv *ic = iconv_get();
548  char *newpath;
549  int err = iconv_convpath(ic, path, &newpath, 0);
550  if (!err) {
551  err = fuse_fs_bmap(ic->next, newpath, blocksize, idx);
552  free(newpath);
553  }
554  return err;
555 }
556 
557 static void *iconv_init(struct fuse_conn_info *conn,
558  struct fuse_config *cfg)
559 {
560  struct iconv *ic = iconv_get();
561  fuse_fs_init(ic->next, conn, cfg);
562  /* Don't touch cfg->nullpath_ok, we can work with
563  either */
564  return ic;
565 }
566 
567 static void iconv_destroy(void *data)
568 {
569  struct iconv *ic = data;
570  fuse_fs_destroy(ic->next);
571  iconv_close(ic->tofs);
572  iconv_close(ic->fromfs);
573  pthread_mutex_destroy(&ic->lock);
574  free(ic->from_code);
575  free(ic->to_code);
576  free(ic);
577 }
578 
579 static const struct fuse_operations iconv_oper = {
580  .destroy = iconv_destroy,
581  .init = iconv_init,
582  .getattr = iconv_getattr,
583  .access = iconv_access,
584  .readlink = iconv_readlink,
585  .opendir = iconv_opendir,
586  .readdir = iconv_readdir,
587  .releasedir = iconv_releasedir,
588  .mknod = iconv_mknod,
589  .mkdir = iconv_mkdir,
590  .symlink = iconv_symlink,
591  .unlink = iconv_unlink,
592  .rmdir = iconv_rmdir,
593  .rename = iconv_rename,
594  .link = iconv_link,
595  .chmod = iconv_chmod,
596  .chown = iconv_chown,
597  .truncate = iconv_truncate,
598  .utimens = iconv_utimens,
599  .create = iconv_create,
600  .open = iconv_open_file,
601  .read_buf = iconv_read_buf,
602  .write_buf = iconv_write_buf,
603  .statfs = iconv_statfs,
604  .flush = iconv_flush,
605  .release = iconv_release,
606  .fsync = iconv_fsync,
607  .fsyncdir = iconv_fsyncdir,
608  .setxattr = iconv_setxattr,
609  .getxattr = iconv_getxattr,
610  .listxattr = iconv_listxattr,
611  .removexattr = iconv_removexattr,
612  .lock = iconv_lock,
613  .flock = iconv_flock,
614  .bmap = iconv_bmap,
615 };
616 
617 static const struct fuse_opt iconv_opts[] = {
618  FUSE_OPT_KEY("-h", 0),
619  FUSE_OPT_KEY("--help", 0),
620  { "from_code=%s", offsetof(struct iconv, from_code), 0 },
621  { "to_code=%s", offsetof(struct iconv, to_code), 1 },
623 };
624 
625 static void iconv_help(void)
626 {
627  char *old = strdup(setlocale(LC_CTYPE, ""));
628  char *charmap = strdup(nl_langinfo(CODESET));
629  setlocale(LC_CTYPE, old);
630  free(old);
631  printf(
632 " -o from_code=CHARSET original encoding of file names (default: UTF-8)\n"
633 " -o to_code=CHARSET new encoding of the file names (default: %s)\n",
634  charmap);
635  free(charmap);
636 }
637 
638 static int iconv_opt_proc(void *data, const char *arg, int key,
639  struct fuse_args *outargs)
640 {
641  (void) data; (void) arg; (void) outargs;
642 
643  if (!key) {
644  iconv_help();
645  return -1;
646  }
647 
648  return 1;
649 }
650 
651 static struct fuse_fs *iconv_new(struct fuse_args *args,
652  struct fuse_fs *next[])
653 {
654  struct fuse_fs *fs;
655  struct iconv *ic;
656  char *old = NULL;
657  const char *from;
658  const char *to;
659 
660  ic = calloc(1, sizeof(struct iconv));
661  if (ic == NULL) {
662  fprintf(stderr, "fuse-iconv: memory allocation failed\n");
663  return NULL;
664  }
665 
666  if (fuse_opt_parse(args, ic, iconv_opts, iconv_opt_proc) == -1)
667  goto out_free;
668 
669  if (!next[0] || next[1]) {
670  fprintf(stderr, "fuse-iconv: exactly one next filesystem required\n");
671  goto out_free;
672  }
673 
674  from = ic->from_code ? ic->from_code : "UTF-8";
675  to = ic->to_code ? ic->to_code : "";
676  /* FIXME: detect charset equivalence? */
677  if (!to[0])
678  old = strdup(setlocale(LC_CTYPE, ""));
679  ic->tofs = iconv_open(from, to);
680  if (ic->tofs == (iconv_t) -1) {
681  fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
682  to, from);
683  goto out_free;
684  }
685  ic->fromfs = iconv_open(to, from);
686  if (ic->tofs == (iconv_t) -1) {
687  fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
688  from, to);
689  goto out_iconv_close_to;
690  }
691  if (old) {
692  setlocale(LC_CTYPE, old);
693  free(old);
694  }
695 
696  ic->next = next[0];
697  fs = fuse_fs_new(&iconv_oper, sizeof(iconv_oper), ic);
698  if (!fs)
699  goto out_iconv_close_from;
700 
701  return fs;
702 
703 out_iconv_close_from:
704  iconv_close(ic->fromfs);
705 out_iconv_close_to:
706  iconv_close(ic->tofs);
707 out_free:
708  free(ic->from_code);
709  free(ic->to_code);
710  free(ic);
711  if (old) {
712  setlocale(LC_CTYPE, old);
713  free(old);
714  }
715  return NULL;
716 }
717 
718 FUSE_REGISTER_MODULE(iconv, iconv_new);
+
fuse_fill_dir_flags
Definition: fuse.h:54
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
fuse_readdir_flags
Definition: fuse.h:42
+ + + +
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98
+
#define FUSE_REGISTER_MODULE(name_, factory_)
Definition: fuse.h:1238
+
#define FUSE_OPT_END
Definition: fuse_opt.h:104
+
void * private_data
Definition: fuse.h:791
+
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
Definition: fuse.c:4760
+ +
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:82
+ + + +
struct fuse_context * fuse_get_context(void)
Definition: fuse.c:4557
+
void(* destroy)(void *private_data)
Definition: fuse.h:580
+
+ + + + diff --git a/doc/html/index.html b/doc/html/index.html new file mode 100644 index 0000000..ad75b1a --- /dev/null +++ b/doc/html/index.html @@ -0,0 +1,66 @@ + + + + + + + +libfuse: libfuse API documentation + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + +
+
+
+
libfuse API documentation
+
+
+

FUSE (Filesystem in Userspace) is an interface for userspace programs to export a filesystem to the Linux kernel. The FUSE project consists of two components: the fuse kernel module (maintained in the regular kernel repositories) and the libfuse userspace library. libfuse provides the reference implementation for communicating with the FUSE kernel module.

+

A FUSE file system is typically implemented as a standalone application that links with libfuse. libfuse provides functions to mount the file system, unmount it, read requests from the kernel, and send responses back.

+

Getting started

+

libfuse offers two APIs: a "high-level", synchronous API, and a "low-level" asynchronous API. In both cases, incoming requests from the kernel are passed to the main program using callbacks. When using the high-level API, the callbacks may work with file names and paths instead of inodes, and processing of a request finishes when the callback function returns. When using the low-level API, the callbacks must work with inodes and responses must be sent explicitly using a separate set of API functions.

+

The high-level API that is primarily specified in fuse.h. The low-level API that is primarily documented in fuse_lowlevel.h.

+

Examples

+

FUSE comes with several examples in the examples directory. A good starting point are hello.c (for the high-level API) and hello_ll.c (for the low-level API).

+

FUSE internals

+

The authoritative source of information about libfuse internals (including the protocol used for communication with the FUSE kernel module) is the source code.

+

However, some people have kindly documented different aspects of FUSE in a more beginner friendly way. While this information is increasingly out of date, it still provides a good overview:

+ +
+ + + + diff --git a/doc/html/invalidate__path_8c.html b/doc/html/invalidate__path_8c.html new file mode 100644 index 0000000..f6a1f0c --- /dev/null +++ b/doc/html/invalidate__path_8c.html @@ -0,0 +1,77 @@ + + + + + + + +libfuse: example/invalidate_path.c File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
invalidate_path.c File Reference
+
+
+
#include <fuse.h>
+#include <fuse_lowlevel.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <pthread.h>
+
+

Go to the source code of this file.

+

Detailed Description

+

This example implements a file system with two files:

    +
  • 'current-time', whose contents change dynamically: it always contains the current time (same as in notify_inval_inode.c).
  • +
  • 'growing', whose size changes dynamically, growing by 1 byte after each update. This aims to check if cached file metadata is also invalidated.
  • +
+

Compilation

+
gcc -Wall
+

Definition in file invalidate_path.c.

+
+ + + + diff --git a/doc/html/invalidate__path_8c_source.html b/doc/html/invalidate__path_8c_source.html new file mode 100644 index 0000000..bd2cbae --- /dev/null +++ b/doc/html/invalidate__path_8c_source.html @@ -0,0 +1,91 @@ + + + + + + + +libfuse: example/invalidate_path.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
invalidate_path.c
+
+
+Go to the documentation of this file.
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2016 Nikolaus Rath <Nikolaus@rath.org>
4  (C) 2017 EditShare LLC <slawek.rudnicki@editshare.com>
5 
6  This program can be distributed under the terms of the GNU GPL.
7  See the file COPYING.
8  */
9 
28 #define FUSE_USE_VERSION 31
29 
30 #include <fuse.h>
31 #include <fuse_lowlevel.h> /* for fuse_cmdline_opts */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <assert.h>
39 #include <stddef.h>
40 #include <unistd.h>
41 #include <pthread.h>
42 
43 /* We can't actually tell the kernel that there is no
44  timeout, so we just send a big value */
45 #define NO_TIMEOUT 500000
46 
47 #define MAX_STR_LEN 128
48 #define TIME_FILE_NAME "current_time"
49 #define TIME_FILE_INO 2
50 #define GROW_FILE_NAME "growing"
51 #define GROW_FILE_INO 3
52 
53 static char time_file_contents[MAX_STR_LEN];
54 static size_t grow_file_size;
55 
56 /* Command line parsing */
57 struct options {
58  int no_notify;
59  int update_interval;
60 };
61 static struct options options = {
62  .no_notify = 0,
63  .update_interval = 1,
64 };
65 
66 #define OPTION(t, p) { t, offsetof(struct options, p), 1 }
67 static const struct fuse_opt option_spec[] = {
68  OPTION("--no-notify", no_notify),
69  OPTION("--update-interval=%d", update_interval),
71 };
72 
73 static void *xmp_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
74 {
75  (void) conn;
76  cfg->entry_timeout = NO_TIMEOUT;
77  cfg->attr_timeout = NO_TIMEOUT;
78  cfg->negative_timeout = 0;
79 
80  return NULL;
81 }
82 
83 static int xmp_getattr(const char *path,
84  struct stat *stbuf, struct fuse_file_info* fi) {
85  (void) fi;
86  if (strcmp(path, "/") == 0) {
87  stbuf->st_ino = 1;
88  stbuf->st_mode = S_IFDIR | 0755;
89  stbuf->st_nlink = 1;
90  } else if (strcmp(path, "/" TIME_FILE_NAME) == 0) {
91  stbuf->st_ino = TIME_FILE_INO;
92  stbuf->st_mode = S_IFREG | 0444;
93  stbuf->st_nlink = 1;
94  stbuf->st_size = strlen(time_file_contents);
95  } else if (strcmp(path, "/" GROW_FILE_NAME) == 0) {
96  stbuf->st_ino = GROW_FILE_INO;
97  stbuf->st_mode = S_IFREG | 0444;
98  stbuf->st_nlink = 1;
99  stbuf->st_size = grow_file_size;
100  } else {
101  return -ENOENT;
102  }
103 
104  return 0;
105 }
106 
107 static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
108  off_t offset, struct fuse_file_info *fi,
109  enum fuse_readdir_flags flags) {
110  (void) fi;
111  (void) offset;
112  (void) flags;
113  if (strcmp(path, "/") != 0) {
114  return -ENOTDIR;
115  } else {
116  (void) filler;
117  (void) buf;
118  struct stat file_stat;
119  xmp_getattr("/" TIME_FILE_NAME, &file_stat, NULL);
120  filler(buf, TIME_FILE_NAME, &file_stat, 0, 0);
121  xmp_getattr("/" GROW_FILE_NAME, &file_stat, NULL);
122  filler(buf, GROW_FILE_NAME, &file_stat, 0, 0);
123  return 0;
124  }
125 }
126 
127 static int xmp_open(const char *path, struct fuse_file_info *fi) {
128  (void) path;
129  /* Make cache persistent even if file is closed,
130  this makes it easier to see the effects */
131  fi->keep_cache = 1;
132  return 0;
133 }
134 
135 static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
136  struct fuse_file_info *fi) {
137  (void) fi;
138  (void) offset;
139  if (strcmp(path, "/" TIME_FILE_NAME) == 0) {
140  int file_length = strlen(time_file_contents);
141  int to_copy = offset + size <= file_length
142  ? size
143  : file_length - offset;
144  memcpy(buf, time_file_contents, to_copy);
145  return to_copy;
146  } else {
147  assert(strcmp(path, "/" GROW_FILE_NAME) == 0);
148  int to_copy = offset + size <= grow_file_size
149  ? size
150  : grow_file_size - offset;
151  memset(buf, 'x', to_copy);
152  return to_copy;
153  }
154 }
155 
156 static struct fuse_operations xmp_oper = {
157  .init = xmp_init,
158  .getattr = xmp_getattr,
159  .readdir = xmp_readdir,
160  .open = xmp_open,
161  .read = xmp_read,
162 };
163 
164 static void update_fs(void) {
165  static int count = 0;
166  struct tm *now;
167  time_t t;
168  t = time(NULL);
169  now = localtime(&t);
170  assert(now != NULL);
171 
172  int time_file_size = strftime(time_file_contents, MAX_STR_LEN,
173  "The current time is %H:%M:%S\n", now);
174  assert(time_file_size != 0);
175 
176  grow_file_size = count++;
177 }
178 
179 static int invalidate(struct fuse *fuse, const char *path) {
180  int status = fuse_invalidate_path(fuse, path);
181  if (status == -ENOENT) {
182  return 0;
183  } else {
184  return status;
185  }
186 }
187 
188 static void* update_fs_loop(void *data) {
189  struct fuse *fuse = (struct fuse*) data;
190 
191  while (1) {
192  update_fs();
193  if (!options.no_notify) {
194  assert(invalidate(fuse, "/" TIME_FILE_NAME) == 0);
195  assert(invalidate(fuse, "/" GROW_FILE_NAME) == 0);
196  }
197  sleep(options.update_interval);
198  }
199  return NULL;
200 }
201 
202 static void show_help(const char *progname)
203 {
204  printf("usage: %s [options] <mountpoint>\n\n", progname);
205  printf("File-system specific options:\n"
206  " --update-interval=<secs> Update-rate of file system contents\n"
207  " --no-notify Disable kernel notifications\n"
208  "\n");
209 }
210 
211 int main(int argc, char *argv[]) {
212  struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
213  struct fuse *fuse;
214  struct fuse_cmdline_opts opts;
215  int res;
216 
217  /* Initialize the files */
218  update_fs();
219 
220  if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1)
221  return 1;
222 
223  if (fuse_parse_cmdline(&args, &opts) != 0)
224  return 1;
225 
226  if (opts.show_version) {
227  printf("FUSE library version %s\n", fuse_pkgversion());
229  res = 0;
230  goto out1;
231  } else if (opts.show_help) {
232  show_help(argv[0]);
234  fuse_lib_help(&args);
235  res = 0;
236  goto out1;
237  } else if (!opts.mountpoint) {
238  fprintf(stderr, "error: no mountpoint specified\n");
239  res = 1;
240  goto out1;
241  }
242 
243  fuse = fuse_new(&args, &xmp_oper, sizeof(xmp_oper), NULL);
244  if (fuse == NULL) {
245  res = 1;
246  goto out1;
247  }
248 
249  if (fuse_mount(fuse,opts.mountpoint) != 0) {
250  res = 1;
251  goto out2;
252  }
253 
254  if (fuse_daemonize(opts.foreground) != 0) {
255  res = 1;
256  goto out3;
257  }
258 
259  pthread_t updater; /* Start thread to update file contents */
260  int ret = pthread_create(&updater, NULL, update_fs_loop, (void *) fuse);
261  if (ret != 0) {
262  fprintf(stderr, "pthread_create failed with %s\n", strerror(ret));
263  return 1;
264  };
265 
266  struct fuse_session *se = fuse_get_session(fuse);
267  if (fuse_set_signal_handlers(se) != 0) {
268  res = 1;
269  goto out3;
270  }
271 
272  if (opts.singlethread)
273  res = fuse_loop(fuse);
274  else
275  res = fuse_loop_mt(fuse, opts.clone_fd);
276  if (res)
277  res = 1;
278 
280 out3:
281  fuse_unmount(fuse);
282 out2:
283  fuse_destroy(fuse);
284 out1:
285  free(opts.mountpoint);
286  fuse_opt_free_args(&args);
287  return res;
288 }
+
int fuse_daemonize(int foreground)
Definition: helper.c:225
+
unsigned long offset
Definition: fuse_opt.h:85
+
int fuse_loop(struct fuse *f)
Definition: fuse.c:4516
+
struct fuse * fuse_new(struct fuse_args *args, const struct fuse_operations *op, size_t op_size, void *private_data)
+
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:397
+
unsigned int keep_cache
Definition: fuse_common.h:51
+
fuse_readdir_flags
Definition: fuse.h:42
+
int fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts)
Definition: helper.c:202
+
void fuse_cmdline_help(void)
Definition: helper.c:129
+
double negative_timeout
Definition: fuse.h:129
+
int fuse_set_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:62
+
void fuse_remove_signal_handlers(struct fuse_session *se)
Definition: fuse_signals.c:79
+ +
void *(* init)(struct fuse_conn_info *conn, struct fuse_config *cfg)
Definition: fuse.h:572
+
void fuse_destroy(struct fuse *f)
Definition: fuse.c:5007
+
void fuse_lowlevel_version(void)
+ +
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:33
+
#define FUSE_OPT_END
Definition: fuse_opt.h:104
+
struct fuse_session * fuse_get_session(struct fuse *f)
Definition: fuse.c:4459
+
int fuse_invalidate_path(struct fuse *f, const char *path)
Definition: fuse.c:4586
+
double attr_timeout
Definition: fuse.h:135
+ +
void fuse_lib_help(struct fuse_args *args)
Definition: fuse.c:4650
+
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:82
+ +
int fuse_mount(struct fuse *f, const char *mountpoint)
Definition: fuse.c:5057
+ + +
void fuse_unmount(struct fuse *f)
Definition: fuse.c:5062
+ +
const char * fuse_pkgversion(void)
Definition: fuse.c:5071
+
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
+
double entry_timeout
Definition: fuse.h:119
+
+ + + + diff --git a/doc/html/ioctl_8c.html b/doc/html/ioctl_8c.html new file mode 100644 index 0000000..45f2dcb --- /dev/null +++ b/doc/html/ioctl_8c.html @@ -0,0 +1,72 @@ + + + + + + + +libfuse: example/ioctl.c File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
ioctl.c File Reference
+
+
+
#include <fuse.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include "ioctl.h"
+
+

Go to the source code of this file.

+

Detailed Description

+

This example illustrates how to write a FUSE file system that can process (a restricted set of) ioctls. It can be tested with the ioctl_client.c program.

+

Compile with:

gcc -Wall ioctl.c `pkg-config fuse3 --cflags --libs` -o ioctl
+

Source code

+
/*
FUSE fioc: FUSE ioctl example
Copyright (C) 2008 SUSE Linux Products GmbH
Copyright (C) 2008 Tejun Heo <teheo@suse.de>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
*/
#define FUSE_USE_VERSION 31
#include <fuse.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include "ioctl.h"
#define FIOC_NAME "fioc"
enum {
FIOC_NONE,
FIOC_ROOT,
FIOC_FILE,
};
static void *fioc_buf;
static size_t fioc_size;
static int fioc_resize(size_t new_size)
{
void *new_buf;
if (new_size == fioc_size)
return 0;
new_buf = realloc(fioc_buf, new_size);
if (!new_buf && new_size)
return -ENOMEM;
if (new_size > fioc_size)
memset(new_buf + fioc_size, 0, new_size - fioc_size);
fioc_buf = new_buf;
fioc_size = new_size;
return 0;
}
static int fioc_expand(size_t new_size)
{
if (new_size > fioc_size)
return fioc_resize(new_size);
return 0;
}
static int fioc_file_type(const char *path)
{
if (strcmp(path, "/") == 0)
return FIOC_ROOT;
if (strcmp(path, "/" FIOC_NAME) == 0)
return FIOC_FILE;
return FIOC_NONE;
}
static int fioc_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi)
{
(void) fi;
stbuf->st_uid = getuid();
stbuf->st_gid = getgid();
stbuf->st_atime = stbuf->st_mtime = time(NULL);
switch (fioc_file_type(path)) {
case FIOC_ROOT:
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
break;
case FIOC_FILE:
stbuf->st_mode = S_IFREG | 0644;
stbuf->st_nlink = 1;
stbuf->st_size = fioc_size;
break;
case FIOC_NONE:
return -ENOENT;
}
return 0;
}
static int fioc_open(const char *path, struct fuse_file_info *fi)
{
(void) fi;
if (fioc_file_type(path) != FIOC_NONE)
return 0;
return -ENOENT;
}
static int fioc_do_read(char *buf, size_t size, off_t offset)
{
if (offset >= fioc_size)
return 0;
if (size > fioc_size - offset)
size = fioc_size - offset;
memcpy(buf, fioc_buf + offset, size);
return size;
}
static int fioc_read(const char *path, char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
{
(void) fi;
if (fioc_file_type(path) != FIOC_FILE)
return -EINVAL;
return fioc_do_read(buf, size, offset);
}
static int fioc_do_write(const char *buf, size_t size, off_t offset)
{
if (fioc_expand(offset + size))
return -ENOMEM;
memcpy(fioc_buf + offset, buf, size);
return size;
}
static int fioc_write(const char *path, const char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
{
(void) fi;
if (fioc_file_type(path) != FIOC_FILE)
return -EINVAL;
return fioc_do_write(buf, size, offset);
}
static int fioc_truncate(const char *path, off_t size,
struct fuse_file_info *fi)
{
(void) fi;
if (fioc_file_type(path) != FIOC_FILE)
return -EINVAL;
return fioc_resize(size);
}
static int fioc_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags)
{
(void) fi;
(void) offset;
(void) flags;
if (fioc_file_type(path) != FIOC_ROOT)
return -ENOENT;
filler(buf, ".", NULL, 0, 0);
filler(buf, "..", NULL, 0, 0);
filler(buf, FIOC_NAME, NULL, 0, 0);
return 0;
}
static int fioc_ioctl(const char *path, int cmd, void *arg,
struct fuse_file_info *fi, unsigned int flags, void *data)
{
(void) arg;
(void) fi;
(void) flags;
if (fioc_file_type(path) != FIOC_FILE)
return -EINVAL;
if (flags & FUSE_IOCTL_COMPAT)
return -ENOSYS;
switch (cmd) {
case FIOC_GET_SIZE:
*(size_t *)data = fioc_size;
return 0;
case FIOC_SET_SIZE:
fioc_resize(*(size_t *)data);
return 0;
}
return -EINVAL;
}
static struct fuse_operations fioc_oper = {
.getattr = fioc_getattr,
.readdir = fioc_readdir,
.truncate = fioc_truncate,
.open = fioc_open,
.read = fioc_read,
.write = fioc_write,
.ioctl = fioc_ioctl,
};
int main(int argc, char *argv[])
{
return fuse_main(argc, argv, &fioc_oper, NULL);
}
+

Definition in file ioctl.c.

+
+ + + + diff --git a/doc/html/ioctl_8c_source.html b/doc/html/ioctl_8c_source.html new file mode 100644 index 0000000..d0ca726 --- /dev/null +++ b/doc/html/ioctl_8c_source.html @@ -0,0 +1,65 @@ + + + + + + + +libfuse: example/ioctl.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
ioctl.c
+
+
+Go to the documentation of this file.
1 /*
2  FUSE fioc: FUSE ioctl example
3  Copyright (C) 2008 SUSE Linux Products GmbH
4  Copyright (C) 2008 Tejun Heo <teheo@suse.de>
5 
6  This program can be distributed under the terms of the GNU GPL.
7  See the file COPYING.
8 */
9 
25 #define FUSE_USE_VERSION 31
26 
27 #include <fuse.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <time.h>
33 #include <errno.h>
34 
35 #include "ioctl.h"
36 
37 #define FIOC_NAME "fioc"
38 
39 enum {
40  FIOC_NONE,
41  FIOC_ROOT,
42  FIOC_FILE,
43 };
44 
45 static void *fioc_buf;
46 static size_t fioc_size;
47 
48 static int fioc_resize(size_t new_size)
49 {
50  void *new_buf;
51 
52  if (new_size == fioc_size)
53  return 0;
54 
55  new_buf = realloc(fioc_buf, new_size);
56  if (!new_buf && new_size)
57  return -ENOMEM;
58 
59  if (new_size > fioc_size)
60  memset(new_buf + fioc_size, 0, new_size - fioc_size);
61 
62  fioc_buf = new_buf;
63  fioc_size = new_size;
64 
65  return 0;
66 }
67 
68 static int fioc_expand(size_t new_size)
69 {
70  if (new_size > fioc_size)
71  return fioc_resize(new_size);
72  return 0;
73 }
74 
75 static int fioc_file_type(const char *path)
76 {
77  if (strcmp(path, "/") == 0)
78  return FIOC_ROOT;
79  if (strcmp(path, "/" FIOC_NAME) == 0)
80  return FIOC_FILE;
81  return FIOC_NONE;
82 }
83 
84 static int fioc_getattr(const char *path, struct stat *stbuf,
85  struct fuse_file_info *fi)
86 {
87  (void) fi;
88  stbuf->st_uid = getuid();
89  stbuf->st_gid = getgid();
90  stbuf->st_atime = stbuf->st_mtime = time(NULL);
91 
92  switch (fioc_file_type(path)) {
93  case FIOC_ROOT:
94  stbuf->st_mode = S_IFDIR | 0755;
95  stbuf->st_nlink = 2;
96  break;
97  case FIOC_FILE:
98  stbuf->st_mode = S_IFREG | 0644;
99  stbuf->st_nlink = 1;
100  stbuf->st_size = fioc_size;
101  break;
102  case FIOC_NONE:
103  return -ENOENT;
104  }
105 
106  return 0;
107 }
108 
109 static int fioc_open(const char *path, struct fuse_file_info *fi)
110 {
111  (void) fi;
112 
113  if (fioc_file_type(path) != FIOC_NONE)
114  return 0;
115  return -ENOENT;
116 }
117 
118 static int fioc_do_read(char *buf, size_t size, off_t offset)
119 {
120  if (offset >= fioc_size)
121  return 0;
122 
123  if (size > fioc_size - offset)
124  size = fioc_size - offset;
125 
126  memcpy(buf, fioc_buf + offset, size);
127 
128  return size;
129 }
130 
131 static int fioc_read(const char *path, char *buf, size_t size,
132  off_t offset, struct fuse_file_info *fi)
133 {
134  (void) fi;
135 
136  if (fioc_file_type(path) != FIOC_FILE)
137  return -EINVAL;
138 
139  return fioc_do_read(buf, size, offset);
140 }
141 
142 static int fioc_do_write(const char *buf, size_t size, off_t offset)
143 {
144  if (fioc_expand(offset + size))
145  return -ENOMEM;
146 
147  memcpy(fioc_buf + offset, buf, size);
148 
149  return size;
150 }
151 
152 static int fioc_write(const char *path, const char *buf, size_t size,
153  off_t offset, struct fuse_file_info *fi)
154 {
155  (void) fi;
156 
157  if (fioc_file_type(path) != FIOC_FILE)
158  return -EINVAL;
159 
160  return fioc_do_write(buf, size, offset);
161 }
162 
163 static int fioc_truncate(const char *path, off_t size,
164  struct fuse_file_info *fi)
165 {
166  (void) fi;
167  if (fioc_file_type(path) != FIOC_FILE)
168  return -EINVAL;
169 
170  return fioc_resize(size);
171 }
172 
173 static int fioc_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
174  off_t offset, struct fuse_file_info *fi,
175  enum fuse_readdir_flags flags)
176 {
177  (void) fi;
178  (void) offset;
179  (void) flags;
180 
181  if (fioc_file_type(path) != FIOC_ROOT)
182  return -ENOENT;
183 
184  filler(buf, ".", NULL, 0, 0);
185  filler(buf, "..", NULL, 0, 0);
186  filler(buf, FIOC_NAME, NULL, 0, 0);
187 
188  return 0;
189 }
190 
191 static int fioc_ioctl(const char *path, int cmd, void *arg,
192  struct fuse_file_info *fi, unsigned int flags, void *data)
193 {
194  (void) arg;
195  (void) fi;
196  (void) flags;
197 
198  if (fioc_file_type(path) != FIOC_FILE)
199  return -EINVAL;
200 
201  if (flags & FUSE_IOCTL_COMPAT)
202  return -ENOSYS;
203 
204  switch (cmd) {
205  case FIOC_GET_SIZE:
206  *(size_t *)data = fioc_size;
207  return 0;
208 
209  case FIOC_SET_SIZE:
210  fioc_resize(*(size_t *)data);
211  return 0;
212  }
213 
214  return -EINVAL;
215 }
216 
217 static struct fuse_operations fioc_oper = {
218  .getattr = fioc_getattr,
219  .readdir = fioc_readdir,
220  .truncate = fioc_truncate,
221  .open = fioc_open,
222  .read = fioc_read,
223  .write = fioc_write,
224  .ioctl = fioc_ioctl,
225 };
226 
227 int main(int argc, char *argv[])
228 {
229  return fuse_main(argc, argv, &fioc_oper, NULL);
230 }
fuse_readdir_flags
Definition: fuse.h:42
+ + +
int(* getattr)(const char *, struct stat *, struct fuse_file_info *fi)
Definition: fuse.h:311
+
#define FUSE_IOCTL_COMPAT
Definition: fuse_common.h:329
+ +
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition: fuse.h:82
+ +
#define fuse_main(argc, argv, op, private_data)
Definition: fuse.h:855
+
+ + + + diff --git a/doc/html/ioctl_8h.html b/doc/html/ioctl_8h.html new file mode 100644 index 0000000..293541b --- /dev/null +++ b/doc/html/ioctl_8h.html @@ -0,0 +1,65 @@ + + + + + + + +libfuse: example/ioctl.h File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
ioctl.h File Reference
+
+
+
#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/ioctl.h>
+
+

Go to the source code of this file.

+

Detailed Description

+

Header file to share definitions between the ioctl.c example file system and the ioctl_client.c test program.

+
/*
FUSE-ioctl: ioctl support for FUSE
Copyright (C) 2008 SUSE Linux Products GmbH
Copyright (C) 2008 Tejun Heo <teheo@suse.de>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
*/
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
enum {
FIOC_GET_SIZE = _IOR('E', 0, size_t),
FIOC_SET_SIZE = _IOW('E', 1, size_t),
/*
* The following two ioctls don't follow usual encoding rules
* and transfer variable amount of data.
*/
FIOC_READ = _IO('E', 2),
FIOC_WRITE = _IO('E', 3),
};
struct fioc_rw_arg {
off_t offset;
void *buf;
size_t size;
size_t prev_size; /* out param for previous total size */
size_t new_size; /* out param for new total size */
};
+

Definition in file ioctl.h.

+
+ + + + diff --git a/doc/html/ioctl_8h_source.html b/doc/html/ioctl_8h_source.html new file mode 100644 index 0000000..1259500 --- /dev/null +++ b/doc/html/ioctl_8h_source.html @@ -0,0 +1,56 @@ + + + + + + + +libfuse: example/ioctl.h Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
ioctl.h
+
+
+Go to the documentation of this file.
1 /*
2  FUSE-ioctl: ioctl support for FUSE
3  Copyright (C) 2008 SUSE Linux Products GmbH
4  Copyright (C) 2008 Tejun Heo <teheo@suse.de>
5 
6  This program can be distributed under the terms of the GNU GPL.
7  See the file COPYING.
8 */
9 
20 #include <sys/types.h>
21 #include <sys/uio.h>
22 #include <sys/ioctl.h>
23 
24 enum {
25  FIOC_GET_SIZE = _IOR('E', 0, size_t),
26  FIOC_SET_SIZE = _IOW('E', 1, size_t),
27 
28  /*
29  * The following two ioctls don't follow usual encoding rules
30  * and transfer variable amount of data.
31  */
32  FIOC_READ = _IO('E', 2),
33  FIOC_WRITE = _IO('E', 3),
34 };
35 
36 struct fioc_rw_arg {
37  off_t offset;
38  void *buf;
39  size_t size;
40  size_t prev_size; /* out param for previous total size */
41  size_t new_size; /* out param for new total size */
42 };
+ + + + diff --git a/doc/html/ioctl__client_8c.html b/doc/html/ioctl__client_8c.html new file mode 100644 index 0000000..a4879bd --- /dev/null +++ b/doc/html/ioctl__client_8c.html @@ -0,0 +1,73 @@ + + + + + + + +libfuse: example/ioctl_client.c File Reference + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
ioctl_client.c File Reference
+
+
+
#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include "ioctl.h"
+
+

Go to the source code of this file.

+

Detailed Description

+

This program tests the ioctl.c example file systsem.

+

Compile with:

gcc -Wall ioctl_client.c -o ioctl_client
+

Source code

+
/*
FUSE fioclient: FUSE ioctl example client
Copyright (C) 2008 SUSE Linux Products GmbH
Copyright (C) 2008 Tejun Heo <teheo@suse.de>
This program tests the ioctl.c example file systsem.
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
*/
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include "ioctl.h"
const char *usage =
"Usage: fioclient FIOC_FILE [size]\n"
"\n"
"Get size if <size> is omitted, set size otherwise\n"
"\n";
int main(int argc, char **argv)
{
size_t size;
int fd;
if (argc < 2) {
fprintf(stderr, "%s", usage);
return 1;
}
fd = open(argv[1], O_RDWR);
if (fd < 0) {
perror("open");
return 1;
}
if (argc == 2) {
if (ioctl(fd, FIOC_GET_SIZE, &size)) {
perror("ioctl");
return 1;
}
printf("%zu\n", size);
} else {
size = strtoul(argv[2], NULL, 0);
if (ioctl(fd, FIOC_SET_SIZE, &size)) {
perror("ioctl");
return 1;
}
}
return 0;
}
+

Definition in file ioctl_client.c.

+
+ + + + diff --git a/doc/html/ioctl__client_8c_source.html b/doc/html/ioctl__client_8c_source.html new file mode 100644 index 0000000..d1df595 --- /dev/null +++ b/doc/html/ioctl__client_8c_source.html @@ -0,0 +1,57 @@ + + + + + + + +libfuse: example/ioctl_client.c Source File + + + + + + +
+
+ + + + + + +
+
libfuse +
+
+
+ + + + + + + +
+
+
+
ioctl_client.c
+
+
+Go to the documentation of this file.
1 /*
2  FUSE fioclient: FUSE ioctl example client
3  Copyright (C) 2008 SUSE Linux Products GmbH
4  Copyright (C) 2008 Tejun Heo <teheo@suse.de>
5 
6  This program tests the ioctl.c example file systsem.
7 
8  This program can be distributed under the terms of the GNU GPL.
9  See the file COPYING.
10 */
11 
24 #include <sys/types.h>
25 #include <fcntl.h>
26 #include <sys/stat.h>
27 #include <sys/ioctl.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <ctype.h>
31 #include <errno.h>
32 #include "ioctl.h"
33 
34 const char *usage =
35 "Usage: fioclient FIOC_FILE [size]\n"
36 "\n"
37 "Get size if <size> is omitted, set size otherwise\n"
38 "\n";
39 
40 int main(int argc, char **argv)
41 {
42  size_t size;
43  int fd;
44 
45  if (argc < 2) {
46  fprintf(stderr, "%s", usage);
47  return 1;
48  }
49 
50  fd = open(argv[1], O_RDWR);
51  if (fd < 0) {
52  perror("open");
53  return 1;
54  }
55 
56  if (argc == 2) {
57  if (ioctl(fd, FIOC_GET_SIZE, &size)) {
58  perror("ioctl");
59  return 1;
60  }
61  printf("%zu\n", size);
62  } else {
63  size = strtoul(argv[2], NULL, 0);
64  if (ioctl(fd, FIOC_SET_SIZE, &size)) {
65  perror("ioctl");
66  return 1;
67  }
68  }
69  return 0;
70 }
+
+ + + + diff --git a/doc/html/jquery.js b/doc/html/jquery.js new file mode 100644 index 0000000..3f1abfb --- /dev/null +++ b/doc/html/jquery.js @@ -0,0 +1,87 @@ +/* + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/* + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/* + * jQuery UI 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/* + * jQuery UI Widget 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Widget + */ +(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/* + * jQuery UI Mouse 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/* + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('